java - Spring Security - 为什么我无法登录我的应用程序?

标签 java spring spring-mvc spring-security

我在尝试登录我的应用程序时遇到了一个有点尴尬的问题。

我的 Spring security protected void configure(HttpSecurity http) throws Exception 定义为:

protected void configure(HttpSecurity http) throws Exception {
    System.out.println(http);
    http
        .formLogin()
            .loginPage("/login")
            .usernameParameter("ssoId")
            .passwordParameter("password")
            .and()

        .authorizeRequests()
            // I admit that this section needs some work
            .antMatchers("/", "/home/*", "/alert/*", "/scheduler/*", "/agent/*", "/ftp/*", "/smtp/*", "/sql/*").access("hasRole('USER')")
            .antMatchers("/benefit/*", "/client/*", "/contract/*", "/role/*", "/structure/*", "/term/*").access("hasRole('USER')")
            .antMatchers("/", "/home/*", "/alert/*", "/scheduler/*", "/agent/*", "/ftp/*", "/smtp/*", "/sql/*").access("hasRole('ADMIN')")
            .antMatchers("/benefit/*", "/client/*", "/contract/*", "/role/*", "/structure/*", "/term/*").access("hasRole('ADMIN')")
            .antMatchers("/admin/**").access("hasRole('ADMIN')")
            .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")

            .and()
                .rememberMe().rememberMeParameter("remember-me").tokenRepository(persistentTokenRepository()).tokenValiditySeconds(86400)
            .and()
                .csrf()
            .and()
                .exceptionHandling().accessDeniedPage("/accessDenied");
}

应用程序顺利加载并转到 /login 页面。但是当我尝试使用用户 master 登录并提供正确的密码时,它只是返回到 /login 页面。

我的登录 Controller 是:

@Controller
public class LoginController {

    @Autowired
    UserProfileService userProfileService;

    @Autowired
    UserService userService;

    @RequestMapping(value = { "/", "/home", "/welcome" }, method = RequestMethod.GET)
    public String index(Principal principal) {
        return principal != null ? "home/homeSignedIn" : "home/homeNotSignedIn";
    }

    @RequestMapping(value = "/login")
    public String loginPage() {
        return "login";
    }

    @RequestMapping(value="/logout", method = RequestMethod.GET)
    public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null){    
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return "redirect:/login?logout";
    }

    private String getPrincipal(){
        String userName = null;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        if (principal instanceof UserDetails) {
            userName = ((UserDetails)principal).getUsername();
        } else {
            userName = principal.toString();
        }
        return userName;
    }

    @ModelAttribute("roles")
    public List<UserProfile> initializeProfiles() {
        return userProfileService.findAll();
    }
}

用户

@Entity
@Table(name="user")
public class User extends BasePojo {

    @NotEmpty
    @Column(name="sso_id", unique=true, nullable=false)
    private String ssoId;

    @NotEmpty
    @Column(name="password", nullable=false)
    private String password;

    @NotEmpty
    @Column(name="first_name")
    private String firstName;

    @NotEmpty
    @Column(name="last_name")
    private String lastName;

    @Column(name="email", nullable=false)
    private String email;

    @Column(name="state", nullable=false)
    private String state=UserState.ACTIVE.getState();

    @ManyToMany(fetch = FetchType.EAGER)
    @Fetch(FetchMode.SELECT)
    @JoinTable(name = "hrm_user_user_profile", 
        joinColumns = { @JoinColumn(name = "id_user", referencedColumnName="id") },
        inverseJoinColumns = { @JoinColumn(name = "id_profile", referencedColumnName="id") })
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    private Set<UserProfile> userProfiles;

用户资料:

@Entity
@Table(name="user_profile")
public class UserProfile extends BasePojo {

private static final long serialVersionUID = 1L;

    @Column(name="type", length=15, unique=true, nullable=false)
    private String type = UserProfileType.USER.getUserProfileType();

    // Constructor used only for initial data loading, not used after
    public UserProfile() {
    }

    // Constructor used only for initial data loading, not used after
    public UserProfile(String type) {
        super();
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

用户状态:

public enum UserState {

    LOCKED("state.locked"),
    INACTIVE("state.inactive"),
    ACTIVE("state.active");

    String state;

    private UserState(final String state){
        this.state = state;
    }

    public String getState(){
        return state;
    }

我迷路了。我能得到一些帮助吗?

最佳答案

我相信您已正确验证用户身份。但是,您的/login POST 处理程序方法需要确保后续请求在其 header 中包含 cookie 或 token 。

这样,将应用您设置的如下规则

        .antMatchers("/", "/home/*", "/alert/*", "/scheduler/*", "/agent/*", "/ftp/*", "/smtp/*", "/sql/*").access("hasRole('USER')")
        .antMatchers("/benefit/*", "/client/*", "/contract/*", "/role/*", "/structure/*", "/term/*").access("hasRole('USER')")
        .antMatchers("/", "/home/*", "/alert/*", "/scheduler/*", "/agent/*", "/ftp/*", "/smtp/*", "/sql/*").access("hasRole('ADMIN')")
        .antMatchers("/benefit/*", "/client/*", "/contract/*", "/role/*", "/structure/*", "/term/*").access("hasRole('ADMIN')")
        .antMatchers("/admin/**").access("hasRole('ADMIN')")
        .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")

例如,假设用户正在尝试访问/home。由于用户未通过身份验证,他将被重定向到登录页面。用户输入他的用户名和密码,现在就通过了身份验证。完成后,默认情况下 spring security 会将用户重定向到返回 URL/home。默认情况下,spring security 会在响应中添加一个 cookie,以便每个后续请求都在请求中包含该 cookie。我相信您的情况不会发生这种情况。我想更多地了解您的 spring 安全配置。用户身份验证是如何进行的?它是内存中的身份验证吗?还是数据源认证?

关于java - Spring Security - 为什么我无法登录我的应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37177343/

相关文章:

java - 使用 Select 元素的 HDIV secret 性真实问题

java - "xmlns:log4j"是 <log4j :configuration> tag? 的必需属性吗

java - OSX 上使用 javax.sound.midi 的 Midi 设备

Spring Boot 2 - 基于过滤器的 JWT Spring Security 实现中的 403 而不是 401

json - 将json对象发送到spring MVC中的GET方法

java - 修改静态资源的服务路径

Java 处理 - 使用 text() 但窗口上没有显示任何内容

java - + 如何在 JAVA 中处理字符串

java - 为什么我不能在具有基于注释的配置的不同包中使用相同的 Controller 名称?

java - Spring MVC validator 注解 + 自定义验证