2016-05-12 13 views
3

Ich habe ein etwas peinliches Problem beim Versuch, mich in meine Anwendung einzuloggen.Frühlingssicherheit - warum kann ich mich nicht in meine Anwendung einloggen?

My Spring Security protected void configure(HttpSecurity http) throws Exception ist definiert als:

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

Die Anwendung lädt sich schön und geht zum /login Seite. Aber wenn ich versuche, mit dem Benutzer master zu loggen und das korrekte Passwort zur Verfügung zu stellen, kehrt es einfach zur /login Seite zurück.

Mein Login-Controller ist:

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

Ich bin hier verloren. Kann ich Hilfe bekommen?

+1

Haben Sie die DEBUG-Protokollierung für Spring Security aktiviert? Was sagt es? – holmis83

+0

Ich habe es geschafft, die DEBUG-Protokollierung zu aktivieren, aber ich bin überwältigt von zu vielen Stack-Traces und versuche herauszufinden, wo das Problem liegt. – gtludwig

+0

Zwei Ausgaben haben meine Aufmerksamkeit erregt: 'SecurityContextHolder nicht mit anonymen Token gefüllt, wie es bereits enthalten: 'org.sprin[email protected]9055e4a6: Principal: anonymousUser; Anmeldeinformationen: [GESCHÜTZT]; Authentifiziert: wahr; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: ACF7917E21FC1061F792C959AD0E1323; Erteilte Berechtigungen: ROLE_ANONYMOUS'' – gtludwig

Antwort

2

Ich glaube, dass Sie den Benutzer richtig authentifiziert bekommen. Ihre/login POST-Handler-Methode muss jedoch sicherstellen, dass die nachfolgenden Anforderungen entweder einen Cookie oder ein Token in den Headern haben.

Auf diese Weise wird die von Ihnen festgelegten Regeln, wie unten, werden

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

Zum Beispiel angewandt werden, kann sagen Benutzer zugreifen/home versucht. Da der Benutzer nicht authentifiziert ist, wird er auf die Anmeldeseite umgeleitet. Der Benutzer gibt seinen Benutzernamen und sein Passwort ein und wird jetzt authentifiziert. Sobald dies geschehen ist, leitet die Spring-Sicherheit den Benutzer standardmäßig zur Rückkehr-URL/Home um. Standardmäßig fügt feather security der Antwort ein Cookie hinzu, so dass jede nachfolgende Anfrage dieses Cookie in der Anfrage enthält. Ich glaube, das passiert in deinem Fall nicht. Ich würde gerne mehr über Ihre Sicherheitskonfigurationen im Frühling erfahren. Wie erfolgt die Benutzerauthentifizierung? Ist es eine In-Memory-Authentifizierung? oder Datenquellenauthentifizierung?

+0

Danke, Kumpel! Ich hatte das Problem bereits gelöst. Während meiner (Re-) Neigungskurve von Spring habe ich es geschafft, den Benutzerstatus unverschlüsselt zu setzen, und als ich versuchte, ihn umzuformulieren, ging ich verloren. Ich habe deine Antwort angenommen, weil du dir die Zeit genommen hast auszuhelfen! – gtludwig

+1

Sie sind herzlich willkommen @gtludwig :) – koder23

+1

Ich hatte genau das gleiche Problem. Um für zukünftige Leser klar zu sein, hatte ich einen logischen Fehler in meiner 'UserDetails # isAccountNonLocked' Methode.Also hat mein 'UserDetailsService' implizit * mein Benutzerobjekt korrekt gefunden und das Passwort stimmt überein * war erfolgreich, aber Spring Security muss irgendwann eine Reihe von Checks für den User/Principal durchführen, die es zurückgeben soll, und einen von Das ist die 'isAccountNonLocked' Methode. Mein Fehler gab fälschlicherweise 'false' zurück, wenn diese Methode aufgerufen wurde, was dasselbe ist wie' isAccountLocked == true' ... es war ein doppelt negativer Fehler ... doh !!! – smeeb

Verwandte Themen