【问题标题】:Why Spring Security is not working in my Spring Boot project?为什么 Spring Security 在我的 Spring Boot 项目中不起作用?
【发布时间】:2016-12-15 04:55:28
【问题描述】:

我的问题!为什么一旦管理员或用户登录后,他们就无法进入他们的仪表板。它更新页面“/”或“/home”,但不去 到 UserDashboards 或 AdminDashboards?! 我正在尝试使用 Spring 安全性和 DB() 为应用程序配置 Spring Boot。 我的 home.jsp 中有登录表单。用户可以在模态窗口中登录或注册我的网站。 我将只展示 home.jsp 的一部分

<!-- Header -->
<li><a href="#contact" class="smoothScroll"><spring:message code="nav.section.link5"/></a></li>
        <c:if test="${email == null}">
        <li><a href="" class="smoothScroll" data-toggle="modal" data-target="#modal-1"><spring:message code="nav.section.link6"/></a></li>
        <li><a href="" class="smoothScroll" data-toggle="modal" data-target="#modal-2"><spring:message code="nav.section.link9"/></a></li>
        </c:if>
        <c:if test="${email != null}">
          <li><a href="/dashboards" class="smoothScroll">${email}</a></li>
          <li><a href="/accountLogout" class="smoothScroll"><spring:message code="nav.section.link10"></spring:message></a> </li>
        </c:if>

<!-- modal login
================================================== -->
<div class="modal" id="modal-1">
  <div class="modal-dialog modal-sm">
    <div class="modal-content">
      <div class="modal-body">
        <div class="btn-group btn-group-justified" role="group" aria-label="...">
          <div class="btn-group" role="group">
            <button type="button" class="btn btn-default active"><spring:message code="nav.section.link6"/></button>
          </div>
          <div class="btn-group" role="group">
            <button type="button" class="btn btn-default" data-toggle="modal" data-target="#modal-2" data-dismiss="modal"><spring:message code="nav.section.link9"/></button>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <div align="center">
          <ul class="sign-social-icon">
            <li><a href="/facebookLogin" class="fa fa-facebook wow fadeIn sign-facebook" data-wow-delay="0.3s"></a></li>
            <li><a href="/twitterLogin" class="fa fa-twitter wow fadeIn sign-twitter" data-wow-delay="0.6s"></a></li>
            <li><a href="/linkedinLogin" class="fa fa-linkedin wow fadeIn sign-linkedin" data-wow-delay="0.9s"></a></li>
            <li><a href="/googleLogin" class="fa fa-google-plus wow fadeIn sign-google" data-wow-delay="1.2s"></a></li>
          </ul>
        </div>

        <div class="or">
          <p><spring:message code="modal.section.h3"/></p>
        </div >

        <form:form method="post" action="/userLogin" id="contact-formL" class="form-horizontal">

        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

          <div class="control-group controls">
            <input type="email" class="reg"  placeholder="<spring:message code="modal.section.h6"/>" name="email" id="emailL" value="${dto.email}">
          </div>
          <div class="control-group controls ">
            <input type="password" class="reg"  id="passwordL" placeholder="<spring:message code="modal.section.h7"/>" name="password"  value="${dto.password}" >
          </div>

          <div class="sign form-actions">
            <input role="button" type="submit" class="btn btn-primary  btn-block" value="<spring:message code="nav.section.link6"/>">
          </div>

        </form:form>

        <%--<div class="fmp">--%>
          <%--<a><spring:message code="modal.section.h4"/></a>--%>
        <%--</div>--%>
      </div>
    </div>
  </div>
</div>

<!-- modal registration
================================================== -->

<div class="modal" id="modal-2">
  <div class="modal-dialog modal-sm">
    <div class="modal-content">
      <div class="modal-body">
        <div class="btn-group btn-group-justified" role="group" aria-label="...">
          <div class="btn-group" role="group">
            <button type="button" class="btn btn-default" data-toggle="modal" data-target="#modal-1" data-dismiss="modal" ><spring:message code="nav.section.link6"/></button>
          </div>
          <div class="btn-group" role="group">
            <button type="button" class="btn btn-default active"><spring:message code="nav.section.link9"/></button>
          </div>
        </div>
      </div>
      <div class="modal-footer">

        <div align="center">
          <ul class="sign-social-icon">
            <li><a href="/facebookLogin" class="fa fa-facebook wow fadeIn sign-facebook" data-wow-delay="0.3s"></a></li>
            <li><a href="/twitterLogin" class="fa fa-twitter wow fadeIn sign-twitter" data-wow-delay="0.6s"></a></li>
            <li><a href="/linkedinLogin" class="fa fa-linkedin wow fadeIn sign-linkedin" data-wow-delay="0.9s"></a></li>
            <li><a href="/googleLogin" class="fa fa-google-plus wow fadeIn sign-google" data-wow-delay="1.2s"></a></li>
          </ul>
        </div>

        <div class="or">
          <p><spring:message code="modal.section.h3"/></p>
        </div>

        <form:form action="/saveUser" modelAttribute="dto" name="myForm" id="contact-form" class="form-horizontal">
          <div class="control-group controls">
                <input type="email" class="reg"  placeholder="<spring:message code="modal.section.h6"/>" name="email" id="email" value="${dto.email}">
            </div>
          <div class="control-group controls ">
            <input type="password" class="reg"  id="password" placeholder="<spring:message code="modal.section.h7"/>" name="password"  value="${dto.password}" >
          </div>
          <div class="control-group controls">
            <input type="password" class="reg" id="conf"  placeholder="<spring:message code="modal.section.h8"/>" name="conf">
          </div>
          <div class="sign form-actions">
            <input role="button" type="submit" class="btn btn-primary  btn-block" value="<spring:message code="nav.section.link9"/>">
          </div>
        </form:form>

        <div class="policy">
          <spring:message code="modal.section.h5"/>        </div>
      </div>
    </div>
  </div>
</div>

这是我在 HomeController.class 中的登录方法:

 @RequestMapping(value = "/userLogin", method = RequestMethod.POST)
    public String updateOne(@RequestParam(required = true) String email, @RequestParam(required = true) String password, HttpServletRequest request) throws SQLException {
        HttpSession session = request.getSession();
        User user = userService.getByEmail(email);
        System.out.println("проверка пароля и имейла с  БД");
        if (user != null && user.getPassword().equals(password)) {
            session.setAttribute("email", user.getEmail());
            System.out.println("ЛОГИНИТСЯ!!!");
            if (userService.getByEmail(email).getRole().equals(Role.USER)) {
                System.out.println("SALUT USER!!");
                session.setAttribute("user", user);
                return "redirect:/";
            } else if (userService.getByEmail(email).getRole().equals(Role.MODERATOR)) {
                System.out.println("SALUT MODERATOR!!");
                session.setAttribute("moderator", user);
                return "redirect:/";
            } else if (userService.getByEmail(email).getRole().equals(Role.ADMIN)) {
                System.out.println("SALUT ADMIN!!");
                session.setAttribute("admin", user);
                return "redirect:/";
            }

        }
        return "redirect:/loginProblems";

    }

然后用户和管理员必须打开他们的仪表板(使用在 HEADER 中点击按钮 &lt;li&gt;&lt;a href="/dashboards" class="smoothScroll"&gt;${email}&lt;/a&gt;&lt;/li&gt;)。

这是我的 DashboardController.class:

@Controller
public class DashboardsConroller {

    @Autowired
    UserService userService;
    @Autowired
    UserDataService userDataService;

    @RequestMapping(value = "/dashboards", method = RequestMethod.GET)
    public String selectDashboard(HttpServletRequest request) {
        System.out.println("method selectDashboard!!");
        HttpSession session = request.getSession();
        User user = userService.getByEmail((String) session.getAttribute("email"));
        System.out.println("СМОТРИ СЮДА = " + user);
        if (userService.getByEmail(user.getEmail()).getRole().equals(Role.USER)) {
            System.out.println("USER want to open dashboard!!");
            session.setAttribute("user", user);
            return "redirect:/userDash";
        } else if (userService.getByEmail(user.getEmail()).getRole().equals(Role.MODERATOR)) {
            System.out.println("Moderator want to open dashboard!!");
            session.setAttribute("moderator", user);
            return "redirect:/moderatorDash";
        } else if (userService.getByEmail(user.getEmail()).getRole().equals(Role.ADMIN)) {
            System.out.println("ADMIN want to open dashboard!!");
            session.setAttribute("admin", user);
            return "redirect:/adminDash";
        } else {
            System.out.println("LAST ELSE IS WORKING");
            return "redirect:/home";
        }

    }

}

这是我在 AdminDashController.class 中的 showAdminDashboard() 方法:

@PreAuthorize("hasAuthority('ADMIN')")
    @RequestMapping(value = "/adminDash", method = RequestMethod.GET)
    public ModelAndView showAdminDashboard(@ModelAttribute("myUserData") UserData myUserData,
                                           @RequestParam(required = false) String firstName,
                                           @RequestParam(required = false) String secondName,
                                           HttpServletRequest request) throws SQLException {

        ...

    }

这是我在 UserDashController.class 中的 showUserDashboard() 方法:

@PreAuthorize("hasAuthority('USER')")
    @RequestMapping(value = "/userDash", method = RequestMethod.GET)
    public ModelAndView showUserDashboard(@ModelAttribute("myUserData") UserData myUserData,
                                          @RequestParam(required = false) String firstName,
                                          @RequestParam(required = false) String secondName,
                                          HttpServletRequest request) throws SQLException, InstantiationException, IllegalAccessException {

        ...

        return modelAndView;
    }

这是我的 SecurityConfig.class :

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;


    @Override
    public void configure(WebSecurity web) throws Exception {

        web.ignoring().antMatchers("/resources/**");

    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .authorizeRequests()
                .antMatchers("/", "/home", "/userLogin", "/dashboards", "/saveUser").permitAll()
                .antMatchers("/adminDash").hasAuthority("ADMIN")
                .antMatchers("/userDash").hasAuthority("USER")
                .anyRequest().fullyAuthenticated()
                .and()
                .formLogin()
                .loginPage("/")
                .usernameParameter("email")
                .passwordParameter("password")
                .failureUrl("/loginProblems")
                .permitAll()
                .and()
                .logout().logoutRequestMatcher(new AntPathRequestMatcher("/accountLogout"));

    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
    }

}

pom.xml:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

【问题讨论】:

    标签: security spring-security spring-boot


    【解决方案1】:

    为什么一旦管理员或用户登录后,他们就无法进入他们的仪表板。

    这是因为用户没有被正确认证,事实上对于 Spring Security,用户仍然没有被认证。

    当您使用 Spring Security 时,它应该对用户进行身份验证(通过在数据库中查找用户、比较密码、分配角色等)。但是您正在尝试通过您自己的代码(在/userLogin)对用户进行身份验证。

    【讨论】:

    • 是的,你是对的。但是,我试图删除一个方法 /userLogin 并在内存中创建一个角色,就像这样“public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user").password("password").角色("USER"); auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN"); }"
    • 到目前为止,我使用管理员用户而不是数据库中的用户进行测试。还是不行...请告诉我如果我有一个用于登录和注册的模式窗口(/home 或 /),我应该在参数 .loginPage("/") 或 .loginPage("/home") 中写什么或 .loginPage("home.jsp") 或 .loginPage("/userLogin") 在安全配置中?
    • 我建议至少从阅读loginPage 参数的文档开始:docs.spring.io/spring-security/site/docs/4.1.x/apidocs/org/… 在那里您可以找到有效身份验证的要求。另外我建议阅读配置 Spring Security 的示例 (docs.spring.io/spring-security/site/docs/4.1.x/guides/html5) 并尝试应用它。当它开始工作时,添加一些改进(比如内存数据库中的用户)。
    猜你喜欢
    • 1970-01-01
    • 2016-06-23
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 2021-10-11
    • 2017-06-16
    相关资源
    最近更新 更多