package com.xxxx.security.service.authentication;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.NullRememberMeServices;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.Assert;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.xxxx.naiu.xxxx.model.UserLockModel;
import com.xxxx.naiu.xxxx.service.UserLockService;
import com.xxxx.naiu.xxxx.util.StUtils;
import com.xxxx.security.model.Account;
import com.xxxx.security.model.Role;
import com.xxxx.security.model.User;
import com.xxxx.security.service.authorization.GrantAuthorityService;
import com.xxxx.security.util.SecurityUtil;
public class CustomAuthenticationProcessingFilter
//extends AuthenticationProcessingFilter {
extends UsernamePasswordAuthenticationFilter {
private Map<String, UnsuccessfulAuthenticationHandler> failureHandlerMap = new HashMap();
private List<UnsuccessfulAuthenticationHandler> unsuccessfulAuthenticationHandlers = Collections.emptyList();
public Map<String, UnsuccessfulAuthenticationHandler> getFailureHandlerMap() {
return failureHandlerMap;
}
public void setFailureHandlerMap(
Map<String, UnsuccessfulAuthenticationHandler> failureHandlerMap) {
this.failureHandlerMap = failureHandlerMap;
}
public List<UnsuccessfulAuthenticationHandler> getUnsuccessfulAuthenticationHandlers() {
return unsuccessfulAuthenticationHandlers;
}
public void setUnsuccessfulAuthenticationHandlers(
List<UnsuccessfulAuthenticationHandler> unsuccessfulAuthenticationHandlers) {
this.unsuccessfulAuthenticationHandlers = unsuccessfulAuthenticationHandlers;
}
private boolean useDefaultRoleMerge = false;
private ThreadLocal<Account> currentThreadAccount = new ThreadLocal<Account>();
private GrantAuthorityService grantAuthorityService;
private String grantProcessesUrl;
private boolean continueChainBeforeSuccessfulAuthentication = false;
private RememberMeServices rememberMeServices = new NullRememberMeServices();
private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
private String defaultTargetUrl;
private String alwaysUseDefaultTargetUrl;
private String authenticationFailureUrl;
private String defaultFailureUrl;
public String getDefaultFailureUrl() {
return defaultFailureUrl;
}
public void setDefaultFailureUrl(String defaultFailureUrl) {
this.defaultFailureUrl = defaultFailureUrl;
}
public ThreadLocal<Account> getCurrentThreadAccount() {
return currentThreadAccount;
}
public void setCurrentThreadAccount(ThreadLocal<Account> currentThreadAccount) {
this.currentThreadAccount = currentThreadAccount;
}
public RememberMeServices getRememberMeServices() {
return rememberMeServices;
}
public void setRememberMeServices(RememberMeServices rememberMeServices) {
this.rememberMeServices = rememberMeServices;
}
public AuthenticationFailureHandler getFailureHandler() {
return failureHandler;
}
public void setFailureHandler(AuthenticationFailureHandler failureHandler) {
this.failureHandler = failureHandler;
}
public String getDefaultTargetUrl() {
return defaultTargetUrl;
}
public void setDefaultTargetUrl(String defaultTargetUrl) {
this.defaultTargetUrl = defaultTargetUrl;
}
public String getAuthenticationFailureUrl() {
return authenticationFailureUrl;
}
public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
this.authenticationFailureUrl = authenticationFailureUrl;
}
public GrantAuthorityService getGrantAuthorityService() {
return grantAuthorityService;
}
@Autowired
private UserLockService userLockService;
/** CAFCOMPKEY-e36780bd-cb3c-4bb6-9772-60dce44aadea */
// public Authentication attemptAuthentication(HttpServletRequest request)
public Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse response)
throws AuthenticationException {
String username = null;
String password = null;
Map<String, AccountDetailsService> map = WebApplicationContextUtils.getWebApplicationContext(request.getSession()
.getServletContext())
.getBeansOfType(AccountDetailsService.class);
Assert.notEmpty(map, "A AccountDetailsService must be exist");
Account account = null;
AccountAuthenticationException lastException = null;
Iterator<String> iter = map.keySet().iterator();
while (iter.hasNext()) {
String key = iter.next();
AccountDetailsService service = map.get(key);
try {
account = service.obtainAccount(request);
} catch (AccountAuthenticationException e) {
lastException = e;
}
if (account != null) {
break;
}
}
if (account == null) {
throw lastException;
}
currentThreadAccount.set(account);
username = account.getName();
password = account.getPassword();
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
password);
setDetails(request, authRequest);
return getAuthenticationManager().authenticate(authRequest);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
if (!requiresAuthentication(request, response)) {
chain.doFilter(request, response);
return;
}
String uri = request.getRequestURI();
int pathParamIndex = uri.indexOf(';');
if (pathParamIndex > 0) {
// strip everything after the first semi-colon
uri = uri.substring(0, pathParamIndex);
}
if (uri.endsWith(request.getContextPath() + getGrantProcessesUrl())) {
User user = SecurityUtil.getCurrentUser();
String roleId = request.getParameter("roleId");
if (roleId == null) {
Set<Role> roles = user.getRoles();
grantAuthorityService.grantAuthority(roles);
} else {
Role currentRole = null;
Set<Role> roles = user.getRoles();
for (Role role : roles) {
if (roleId.equals(role.getId().toString())) {
currentRole = role;
user.setCurrentRole(currentRole);
break;
}
}
grantAuthorityService.grantAuthority(Collections.singletonList(currentRole));
}
return;
}
super.doFilter(request, response, chain);
}
//20160201
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
throws IOException, ServletException
{
SecurityContextHolder.getContext().setAuthentication(authResult);
User user = (User) authResult.getPrincipal();
//登录成功后首先将登录错误次数归0
UserLockModel userLockModel=new UserLockModel();
userLockModel.setUsername(user.getUsername());
userLockService.updateUserLock(userLockModel,"suc");
Map<String, Object> cachedProperties = user.getCachedProperties();
Account account = currentThreadAccount.get();
Map<String, Object> otherProperties = account.getOtherProperties();
for (Iterator<String> iterator = otherProperties.keySet().iterator();
iterator.hasNext();) {
String str = iterator.next();
cachedProperties.put(str, otherProperties.get(str));
}
if (this.useDefaultRoleMerge) {
Set<Role> roles = user.getRoles();
grantAuthorityService.grantAuthority(roles);
} else {
Set<Role> roles = user.getRoles();
if (roles.size() > 0) {
grantAuthorityService.grantAuthority(roles);
}else{
try {
} catch (Exception e) {
throw new AccountAuthenticationException("error");
}
}
}
String contextPath = request.getContextPath();
response.sendRedirect(contextPath + this.defaultTargetUrl);
}
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
throws IOException, ServletException
{
SecurityContextHolder.clearContext();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Authentication request failed: " + failed.toString());
this.logger.debug("Updated SecurityContextHolder to contain null Authentication");
this.logger.debug("Delegating to authentication failure handler " + this.failureHandler);
}
Object obj=(Object)failed.getExtraInformation();
User user=(User)obj;
if(StUtils.isNnull(user)){
if(!user.isRoot()){
//登录失败,错误次数+1并更新当前时间
UserLockModel userLockModel=new UserLockModel();
userLockModel.setUsername(user.getUsername());
userLockService.updateUserLock(userLockModel,"fail");
}
}
String exceptionClassName = failed.getClass().getName();
this.logger.warn(" # [" + exceptionClassName + "] happend.");
UnsuccessfulAuthenticationHandler handler = null;
if (this.failureHandlerMap.containsKey(exceptionClassName)) {
handler = (UnsuccessfulAuthenticationHandler)this.failureHandlerMap.get(exceptionClassName);
}
else {
for (UnsuccessfulAuthenticationHandler h : this.unsuccessfulAuthenticationHandlers) {
if (exceptionClassName.equals(h.getHandleableExceptioName())) {
handler = h;
this.failureHandlerMap.put(exceptionClassName, h);
break;
}
}
}
if (handler == null) {
this.logger.warn(" # default handler.");
SecurityContextHolder.clearContext();
String contextPath = request.getContextPath();
response.sendRedirect(contextPath + "/security/login.jsp");
}
else {
try {
handler.handlerAuthenticationException(request, response, failed);
SecurityContextHolder.clearContext();
}
catch (Exception e) {
this.logger.error(" # exception happened, when [" + handler.getClass().getName() + "] handlerAuthenticationException.", e);
SecurityContextHolder.clearContext();
String contextPath = request.getContextPath();
response.sendRedirect(contextPath + "/security/login.jsp");
}
}
}
/**
* XXX DOCUMENT ME!
*
* @return XXX DOCUMENT ME!
*/
public String getGrantProcessesUrl() {
return grantProcessesUrl;
}
/**
* XXX DOCUMENT ME!
*
* @param grantProcessesUrl XXX DOCUMENT ME!
*/
public void setGrantProcessesUrl(String grantProcessesUrl) {
this.grantProcessesUrl = grantProcessesUrl;
}
/**
* XXX DOCUMENT ME!
*
* @return XXX DOCUMENT ME!
*/
public boolean isUseDefaultRoleMerge() {
return useDefaultRoleMerge;
}
/**
* XXX DOCUMENT ME!
*
* @param useDefaultRoleMerge XXX DOCUMENT ME!
*/
public void setUseDefaultRoleMerge(boolean useDefaultRoleMerge) {
this.useDefaultRoleMerge = useDefaultRoleMerge;
}
public UserLockService getUserLockService() {
return userLockService;
}
public void setUserLockService(UserLockService userLockService) {
this.userLockService = userLockService;
}
/**
* XXX DOCUMENT ME!
*
* @param grantAuthorityService XXX DOCUMENT ME!
*/
public void setGrantAuthorityService(
GrantAuthorityService grantAuthorityService) {
this.grantAuthorityService = grantAuthorityService;
}
public String getAlwaysUseDefaultTargetUrl() {
return alwaysUseDefaultTargetUrl;
}
public void setAlwaysUseDefaultTargetUrl(String alwaysUseDefaultTargetUrl) {
this.alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl;
}
public boolean isContinueChainBeforeSuccessfulAuthentication() {
return continueChainBeforeSuccessfulAuthentication;
}
public void setContinueChainBeforeSuccessfulAuthentication(
boolean continueChainBeforeSuccessfulAuthentication) {
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
}
}