Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring security - how come I cannot login into my application?

I'm having a somewhat embarrassing problem trying to login to my application.

My Spring security protected void configure(HttpSecurity http) throws Exception is defined as:

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");
}

The application loads up nicely and goes to the /login page. But when I try to log with the user master and provide the correct password, it simply returns to the /login page.

My login controller is:

@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();
    }
}

User

@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;

UserProfile:

@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;
    }
}

UserState:

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;
    }

I'm lost here. Can I get some help?

like image 866
gtludwig Avatar asked May 12 '16 04:05

gtludwig


People also ask

What is the default username and password for Spring Security?

As of Spring Security version 5.7. 1, the default username is user and the password is randomly generated and displayed in the console (e.g. 8e557245-73e2-4286-969a-ff57fe326336 ).


1 Answers

I believe that you are getting the user authenticated correctly. However, your /login POST handler method, needs to make sure that the subsequent requests have either a cookie or a token in its headers.

This way, the rules set by you as below, will be applied

        .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')")

For instance, lets say user is trying to access /home. Since the user is not authenticated, he is redirected to the login page. The user enters his username and password and is authenticated now. Once this is done, spring security by default will redirect the user to the return URL /home. By default, spring security will add a cookie to the response so that every subsequent request contains that cookie in the request. I believe this is not happening in your case. I would like to know more about your spring security configurations. How is the user authentication taking place? Is it an in memory authentication? or Data source authentication?

like image 52
koder23 Avatar answered Oct 30 '22 02:10

koder23