2016-04-12 4 views
0

CustomAuthenticationProviderから返されたUsernamePasswordAuthenticationTokenに現在のUserオブジェクトを配置しようとすると、問題が発生しました。 は、だから私は私の春-のsecurity.xmlを表示する必要が冒頭で、それは次のようになります。ユーザオブジェクトをUsernamePasswordAuthenticationToken(AuthenticationProvider)に入れる方法は?

<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"/> 

持つので、私は私がサインインするために私のメールアドレスとパスワードを入力する場所でページ/サイン/持っています。 AuthenticationProviderの次のコード私はlogin-page = "/ sign/in"として定義したページに常にリダイレクトされています(失敗URLではありません)。ちなみに、ユーザーオブジェクトの代わりにユーザー名だけを入力すると、うまく動作します。だから、鉱山AuthenticationProviderのコードは次です:

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

} 

興味深いです、それは私のテストでは、それが見えます:

@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( "/秘密/ page "))は、default-target-url ="/secret/page "にリダイレクトされていると言います。 私はAuthenticatioManagerで何とか働いたAuthenticationProviderを読んだので、おそらく問題はどこかにありますか? 誰かが私の間違いを説明したり、何が起こったのかを理解したり、わかりやすく役立つリンクを付けたりすることができますか?私はどんな助けにも感謝します。 ありがとうございます。

ADD Userモデル:

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

モデルの構造を表示できますか?クラスにはtoString()クラスが実装されていますか? –

+0

いいえ、toString()の実装は必要ありません...必須ですか?それを見ていない...( 私はユーザーモデルのコードを追加しました – Nickolas

+0

モデルがプリンシパルとして使用される場合は、常にそれを持つ方が良いです。この場合ではありません –

答えて

1

は、私はこの問題は、あなたがUsernamePasswordAuthenticationToken(ユーザー、パスワード)間違った方法を使用していると思います。ここでは、メソッドUsernamePasswordAuthenticationToken は、プリンシパル(通常は文字列のユーザー名)とパスワードの2つの引数を待ちます。

あなたはAuthentification objectからそれらを取得することで効果的ですが、ユーザーオブジェクトはプリンシパルとはみなされません。

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

いくつかの追加のリソース:ここ

はあなたのユーザーオブジェクトと、この時間は同じことを行うことができますlinkです。あなたは使用されますUserDetailsUserDetails

+0

ありがとうございました実際には、 .addUserDetailsで追加のユーザー情報を追加するのではなく、最初から間違った方法を選択したことを理解しています。 – Nickolas

+0

良い「間違った」方法でそれを実行しようとするいくつかの追加リソースを提供しました。それを行う方法を学ぶ:) –

関連する問題