spring Security4 和 oauth2整合 註解+xml混合使用(驗證碼等額外資料驗證)
阿新 • • 發佈:2018-11-27
spring Security4 和 oauth2整合(驗證碼等額外資料驗證)
上一篇寫的自定義使用者名稱密碼驗證,這裡寫驗證碼的驗證,或者其他資訊的驗證。
git地址:https://gitee.com/xiaoyaofeiyang/OauthUmp
spring Security4 和 oauth2整合 註解+xml混合使用(基礎執行篇)
spring Security4 和 oauth2整合 註解+xml混合使用(進階篇)
spring Security4 和 oauth2整合 註解+xml混合使用(授權碼篇)
spring Security4 和 oauth2整合 註解+xml混合使用(注意事項篇)
spring Security4 和 oauth2整合 註解+xml混合使用(替換6位的授權碼)
spring Security4 和 oauth2整合 註解+xml混合使用(替換使用者名稱密碼認證)
spring Security4 和 oauth2整合 註解+xml混合使用(驗證碼等額外資料驗證)
驗證碼等額外資料獲取邏輯
新增OauthAddUserDetails繼承WebAuthenticationDetails,這裡從request裡拿到額外的引數。對比驗證碼,我們需要有一個介面去更新驗證碼,更新完放到session裡,只有這個地方可以拿到request,所以我就在這裡把session裡的驗證碼也拿出來。
package com.ump.oauth.detail;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import com.ump.domain.AppUser;
public class OauthAddUserDetails extends WebAuthenticationDetails{
/**
*
*/
private static final long serialVersionUID = 6975601077710753878L;
private final String token;
private final String sessionToken;
public OauthAddUserDetails(HttpServletRequest request) {
super(request);
token = request.getParameter("imgtoken");
sessionToken = (String) request.getSession().getAttribute("imgtoken");
}
public String getToken() {
return token;
}
public String getSessionToken() {
return sessionToken;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(super.toString()).append("; Token: ").append(this.getToken());
return sb.toString();
}
}
增加AuthenticationDetailsSource
AuthenticationDetailsSource是需要配置在spring security裡的WebSecurityConfigurerAdapter子類裡。
package com.ump.oauth.part;
import javax.servlet.http.HttpServletRequest;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;
import com.ump.oauth.detail.OauthAddUserDetails;
@Component("oauthAuthenticationDetailsSource")
public class OauthAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
@Override
public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
return new OauthAddUserDetails(context);
}
}
AuthenticationProvider的認證邏輯增加驗證碼處理
對比驗證碼,這裡我們做驗證碼的對比工作。部分程式碼是上一篇講到的,按照自己邏輯刪減即可。
package com.ump.oauth.part;
import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import com.ump.oauth.detail.OauthAddUserDetails;
import com.ump.oauth.detail.OauthUserDetails;
@Component
public class OauthAuthenticationProvider implements AuthenticationProvider {
@Autowired
private OauthUserDetailsService oauthUserDetailsService;
/**
* 自定義驗證方式
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//驗證碼等校驗
OauthAddUserDetails details = (OauthAddUserDetails) authentication.getDetails();
System.out.println(details.getToken() + "+++++++++++++++++" + details.getSessionToken());
if (!details.getToken().equalsIgnoreCase(details.getSessionToken())) {
throw new BadCredentialsException("驗證碼錯誤。");
}
//使用者名稱密碼校驗
OauthUserDetails oauthUserDetails = (OauthUserDetails) oauthUserDetailsService
.loadUserByUsername(authentication.getName());
System.out.println(authentication.getName() + "+++++++++++++++++" + authentication.getCredentials());
if (!oauthUserDetails.getUserName().equals(authentication.getName())
|| !oauthUserDetails.getPassword().equals(authentication.getCredentials())) {
throw new BadCredentialsException("使用者名稱或密碼錯誤。");
}
Collection<? extends GrantedAuthority> authorities = oauthUserDetails.getAuthorities();
return new UsernamePasswordAuthenticationToken(oauthUserDetails.getUsername(), oauthUserDetails.getPassword(),
authorities);
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
}
配置authenticationDetailsSource
只需要一個autowired和HttpSecurity一個.authenticationDetailsSource(authenticationDetailsSource)即可。我這裡程式碼多,刪減即可。
package com.ump.oauth.config;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import com.ump.oauth.part.OauthAuthenticationProvider;
@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("myClientDetailsService")
private ClientDetailsService clientDetailsService;
@Autowired
private OauthAuthenticationProvider oauthAuthenticationProvider;
@Autowired
@Qualifier("oauthAuthenticationDetailsSource")
private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(oauthAuthenticationProvider);
}
@Override
public void configure(HttpSecurity http) throws Exception {
SimpleUrlAuthenticationFailureHandler hander = new SimpleUrlAuthenticationFailureHandler();
hander.setUseForward(true);
hander.setDefaultFailureUrl("/authlogin.jsp");
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/oauth/token")
.permitAll().and()
.formLogin().loginPage("/authlogin.jsp")
.usernameParameter("userName").passwordParameter("userPwd")
.authenticationDetailsSource(authenticationDetailsSource)
// .loginProcessingUrl("/login").failureUrl("/index1.jsp")
.loginProcessingUrl("/login").failureHandler(hander)
.and().logout().logoutUrl("/logout");
http.authorizeRequests().antMatchers("/user/**").authenticated();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
@Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}
@Bean
@Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}
這樣就可以了,需要其他資訊驗證,我們就從request裡面拿東西就是了。