![](/img/trans.png)
[英]Spring Security Custom Authentication - AuthenticationProvider vs UserDetailsService
[英]Spring Security: AuthenticationProvider and UserDetailsService not working as expected
關於Spring Security,我有兩個問題。 我在網絡上做了很多研究,但是答案很膚淺,或者對於我的問題來說太復雜了,導致幫助不多。 我試圖在我的應用程序中使用Java配置策略(完全無xml)使用Spring Security。
第一種情況,我有一個SecurityConfiguration類,它擴展了WebSecurityConfigurerAdapter。 在那里,我已經自動連接了loginService(它實現了UserDetailsService),並且已經將AuthenticationManagerBuilder的UserDetailsService定義為我的LoginService。
當我嘗試使用表單登錄時,LoginService成功獲取了User(根據提供的用戶名和密碼),但是以某種方式身份驗證失敗,並且我在瀏覽器中從Tomcat收到403-Access Denied消息。
第二種情況為了解決前面的問題,我創建了一個自定義AuthenticationProvider並將其注入到SecurityConfiguration中。 但是,當我嘗試登錄時,方法authenticate()甚至無法工作。
有誰可以幫助我嗎? 先感謝您
SecurityConfiguration類
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
private final String ADMIN_ROLE = "ADMIN";
private final String EMPLOYEE_ROLE = "EMPLOYEE";
@Autowired
private LoginService loginService;
@Autowired
public void configureGlobal ( AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(loginService);
}
@Override
public void configure( WebSecurity web ) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
@Override
public void configure( HttpSecurity http ) throws Exception {
http
.authorizeRequests()
.antMatchers("/login**", "/doLogin**").permitAll()
.antMatchers("/admin", "/admin/**").hasRole(ADMIN_ROLE)
.anyRequest().authenticated()
.and()
.requiresChannel()
.anyRequest().requiresSecure()
.and()
.formLogin()
.loginPage( "/login" )
.loginProcessingUrl( "/doLogin" )
.defaultSuccessUrl( "/admin" )
.failureUrl( "/login?err=1" )
.usernameParameter( "username" )
.passwordParameter( "password" )
.and()
// This is where the logout page and process is configured. The logout-url is the URL to send
// the user to in order to logout, the logout-success-url is where they are taken if the logout
// is successful, and the delete-cookies and invalidate-session make sure that we clean up after logout
.logout()
.logoutRequestMatcher( new AntPathRequestMatcher( "/logout" ) )
.logoutSuccessUrl( "/login?out=1" )
.deleteCookies( "JSESSIONID" )
.invalidateHttpSession( true )
.and()
// The session management is used to ensure the user only has one session. This isn't
// compulsory but can add some extra security to your application.
.sessionManagement()
.invalidSessionUrl( "/login" )
.maximumSessions( 1 );
}
}
LoginService類
@Service("loginService")
public class LoginService implements UserDetailsService{
@Autowired
private HibernateUserDAO hibernateUserDAO;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
User user = new User();
user.setUsername(username);
List<User> result = hibernateUserDAO.get(user);
user = result.get(0);
return user;
}
}
AuthProvider類
@Component("authProvider")
public class AuthProvider implements AuthenticationProvider {
@Autowired
private LoginService loginService;
@Override
public Authentication authenticate(Authentication auth)
throws AuthenticationException {
String username = auth.getName();
String password = auth.getCredentials().toString();
System.out.println(username + " " + password);
UserDetails user = loginService.loadUserByUsername(username);
System.out.println(user);
if(user != null){
Authentication token = new UsernamePasswordAuthenticationToken(username, password, user.getAuthorities());
return token;
}
return null;
}
@Override
public boolean supports(Class<?> arg0) {
// TODO Auto-generated method stub
return false;
}
}
OBS:此處粘貼的SecurityConfiguration沒有注入AuthProvider,但是作為信息,configureGlobal方法應該像這樣
@Autowired
private AuthProvider authProvider;
@Autowired
public void configureGlobal ( AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
}
問題解決了! 似乎HttpSecurity的hasRole()方法檢查角色是否為“ ROLE_”格式(例如“ ROLE_ADMIN”),並且我的“授權方”列表僅返回角色名稱(例如“ ADMIN”)。 而已。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.