2016-04-12 7 views
0

Ich habe mit einigen Problemen konfrontiert, wenn ich versuche, das aktuelle Benutzerobjekt in das UsernamePasswordAuthenticationToken zu setzen, das von meinem CustomAuthenticationProvider zurückgegeben wird. Also am Anfang Ich brauche meine Feder-security.xml zu zeigen, sieht es wie folgt aus:.Wie wird das Benutzerobjekt in den UsernamePasswordAuthenticationToken (AuthenticationProvider) eingefügt?

<http auto-config="true" use-expressions="true"> 
    <intercept-url pattern="/sign/in" access="isAnonymous()" /> 
    <intercept-url pattern="/sign/up" access="isAnonymous()" /> 
    <intercept-url pattern="/secret/page" access="isAuthenticated()" /> 
    <intercept-url pattern="/sign/out" access="isAuthenticated()" /> 
    <intercept-url pattern="/user/myinfo" access="isAuthenticated()" /> 

    <form-login 
     login-page="/sign/in" 
     default-target-url="/secret/page" 
     authentication-failure-url="/sign/in?failed=1" 
     password-parameter="password" 
     username-parameter="email" 
    /> 
    <csrf disabled="true"/> 
    <logout 
     logout-url="/sign/out" 
    /> 

    </http> 
    <authentication-manager erase-credentials="false"> 
    <authentication-provider ref="customAuth"> 
    </authentication-provider> 
    </authentication-manager> 

    <beans:bean id="customAuth" class="milkiv.easyword.controller.sign.CustomAuthenticationProvider"/> 

Ich habe die Seite/Zeichen/in, wo ich meine E-Mail und Passwort eingeben, um sich anzumelden Also mit dem nächster Code von AuthenticationProvider Ich wurde immer auf die Seite umgeleitet, die ich als Login-Seite = "/ sign/in" definiert habe (nicht Fehler-URL, habe ich überprüft). Übrigens, wenn statt User-Objekt nur Username gesetzt wird, funktioniert es gut. So ist der Code von mir AuthenticationProvider ist der nächste:

@Service(value = "customAuth") 
public class CustomAuthenticationProvider implements AuthenticationProvider { 

    @Autowired 
    public Storages storage; 

    @Override 
    @Transactional 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
    String login = authentication.getName(); 
    String password = authentication.getCredentials().toString(); 
    User user = storage.uSM.findByEmailAndPassword(login, password); 
    if (user == null) { 
     return null; 
    } else { 
     // if to pur here login insted of user it works fine 
     return new UsernamePasswordAuthenticationToken(user, password); 
    } 
    } 

    @Override 
    public boolean supports(Class<?> authentication) { 
    return authentication.equals(UsernamePasswordAuthenticationToken.class); 
    } 

} 

Interessant ist, dass in meinem Test, das sieht:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:resources/spring-context.xml", "classpath:resources/spring-security.xml"}) 
@WebAppConfiguration 
public class InTest { 

    MockMvc mockMvc; 

    Storages storages; 

    @Autowired 
    private Filter springSecurityFilterChain; 

    private final String nickname = "LoremIpsum"; 
    private final String email = "[email protected]"; 
    private final String password = "loreamipsumpassword"; 

    @Autowired 
    WebApplicationContext wac; // cached 

    @Before 
    public void doBeforeTests() { 
    mockMvc = MockMvcBuilders 
     .webAppContextSetup(wac) 
     .addFilters(springSecurityFilterChain) 
     .build(); 
    ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring-context.xml", "resources/spring-security.xml"); 
    storages = context.getBean(Storages.class); 
    } 

    @Test 
    public void testSignIn() throws Exception { 
    mockMvc.perform(
     formLogin() 
      .user("email", email) 
      .password(password) 
    ) 
     .andExpect(redirectedUrl("/secret/page")); 

} }

.andExpectFunction (redirectedUrl ("/ Geheimnis/page ")) sagen, dass ich auf die default-target-url ="/secret/page "umgeleitet wurde, also sieht es danach aus, dass etwas schief geht. Wie ich gelesen habe AuthenticationProvider funktioniert irgendwie mit AuthenticatioManager, vielleicht ist das Problem hier irgendwo? Kann mir jemand meinen Fehler erklären oder helfen, herauszufinden, was passiert, oder einen Link geben, der mir hilft zu verstehen, oder etwas anderes. Ich werde jede Hilfe schätzen. Vielen Dank im Voraus.

ADD User-Modell:

public class User { 
    private int userId; 

    @NotBlank (message = "Email field can not be empty or missed") 
    @Size(min = 5, max = 128, message = "Email field must have from 5 to 128 symbols") 
    @Email(message = "Email field must have email format.") 
    private String email; 

    @NotBlank (message = "Password field can not be empty or missed") 
    @Size (min = 5, max = 32, message = "Password field must have from 5 to 32 symbols") 
    private String password; 

    @NotBlank (message = "Confirm password field can not be empty or missed") 
    @Size (min = 5, max = 32, message = "Confirm password field must have from 5 to 32 symbols") 
    private String confirmPassword; 

    @NotBlank (message = "Nickname field can not be empty or missed") 
    @Size (min = 3, max = 32, message = "Nickname field must have from 3 to 32 symbols") 
    private String nickname; 


    private Date registrationDate; 

    private Set studyLanguages; 

    public User(){ 
    } 

    public int getUserId() { 
    return userId; 
    } 

    public void setUserId(int userId) { 
    this.userId = userId; 
    } 

    public String getEmail() { 
    return email; 
    } 

    public void setEmail(String email) { 
    this.email = email; 
    } 

    public String getPassword() { 
    return password; 
    } 

    public void setPassword(String password) { 
    this.password = password; 
    } 

    public String getNickname() { 
    return nickname; 
    } 

    public void setNickname(String nickname) { 
    this.nickname = nickname; 
    } 

    public Date getRegistrationDate() { 
    return registrationDate; 
    } 

    public void setRegistrationDate(Date registration_date) { 
    this.registrationDate = registration_date; 
    } 

    public Set getStudyLanguages() { 
    return studyLanguages; 
    } 

    public void setStudyLanguages(Set studyLanguages) { 
    this.studyLanguages = studyLanguages; 
    } 


    public String getConfirmPassword() { 
    return confirmPassword; 
    } 

    public void setConfirmPassword(String confirmPassword) { 
    this.confirmPassword = confirmPassword; 
    } 
} 
+1

Können Sie die Struktur des Modells Benutzer zeigen? Und hat die Klasse eine toString() Klasse implementiert? –

+0

nein, es hat keine toString() Implementierung ... Ist es erforderlich? Ich habe es nicht gesehen ... ( Ich habe Benutzer-Modell-Code hinzugefügt. – Nickolas

+0

Es ist immer besser, es zu haben, wenn das Modell als Prinzipal verwendet werden soll. Nicht in diesem Fall. –

Antwort

1

ich glaube, das Problem ist, dass Sie die UsernamePasswordAuthenticationToken verwenden (Benutzer, Passwort) in die falsche Richtung. Hier wartet die Methode UsernamePasswordAuthenticationToken auf zwei Argumente: einen Principal (normalerweise einen String-Benutzernamen) und ein Passwort.

Sie sind gut, indem Sie sie von der Authentification object bekommen, aber das Benutzerobjekt gilt nicht als Prinzipal, die Anmeldung ist.

@Service(value = "customAuth") 
public class CustomAuthenticationProvider implements AuthenticationProvider { 

    @Autowired 
    public Storages storage; 

    @Override 
    @Transactional 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
    String login = authentication.getName(); 
    String password = authentication.getCredentials().toString(); 
    User user = storage.uSM.findByEmailAndPassword(login, password); 
    if (user == null) { 
     return null; 
    } else { 
     // Here use the user object to only check if the user exists in the database if not null use his login (principal) and password 
     return new UsernamePasswordAuthenticationToken(login, password); 
    } 
    } 

    @Override 
    public boolean supports(Class<?> authentication) { 
    return authentication.equals(UsernamePasswordAuthenticationToken.class); 
    } 
} 

zusätzliche Ressourcen aufgeführt:

Hier ist ein link wo Sie diesmal die gleiche Sache mit Ihrem Benutzerobjekt zu tun. Sie verwenden UserDetails und UserDetails

+0

Vielen Dank für Ihre Erklärung. Ich verstehe, dass ich den falschen Weg von Anfang an gewählt habe, anstatt meine zusätzlichen Benutzerinformationen durch die .addUserDetails hinzugefügt. – Nickolas

+0

Ich habe Ihnen einige zusätzliche Ressourcen zur Verfügung gestellt, um es mit dem guten "falschen" Weg zu versuchen. Überprüfen Sie sie und ich ermutige um zu lernen, wie es geht :) –

Verwandte Themen