first commit
This commit is contained in:
102
springboot-shiro-configure/pom.xml
Normal file
102
springboot-shiro-configure/pom.xml
Normal file
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>shiro-springboot-demo</artifactId>
|
||||
<groupId>demo.xinwin</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>springboot-shiro-configure</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-web</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-ehcache</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-quartz</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
</dependency>
|
||||
<!-- @ConfigurationProperties annotation processing (metadata for IDEs) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>${springboot.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<compilerVersion>${java.version}</compilerVersion>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* This guy is lazy, nothing left.
|
||||
*
|
||||
* @author 张劲航
|
||||
*/
|
||||
public class FormSignInFilter extends FormAuthenticationFilter {
|
||||
|
||||
@Override
|
||||
protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
|
||||
request.setAttribute(getFailureKeyAttribute(), ae);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void redirectToLogin(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
|
||||
try {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
String contentType = request.getContentType();
|
||||
if (contentType != null && contentType.contains("application/json")) {
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.print("{\"error\":\"登录超时,请重新登录。\"}");
|
||||
} else {
|
||||
super.redirectToLogin(servletRequest, servletResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
super.redirectToLogin(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.ExcessiveAttemptsException;
|
||||
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
|
||||
import org.apache.shiro.cache.Cache;
|
||||
import org.apache.shiro.cache.CacheManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RetryLimitHashedCredentialsMatcher.class);
|
||||
|
||||
private Cache<String, AtomicInteger> passwordRetryCache;
|
||||
private int retryMax = 5;
|
||||
|
||||
public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {
|
||||
passwordRetryCache = cacheManager.getCache("passwordRetryCache");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws ExcessiveAttemptsException {
|
||||
String username = (String)token.getPrincipal();
|
||||
AtomicInteger retryCount = passwordRetryCache.get(username);
|
||||
|
||||
if(retryCount == null) {
|
||||
retryCount = new AtomicInteger(0);
|
||||
passwordRetryCache.put(username, retryCount);
|
||||
}
|
||||
if(retryCount.incrementAndGet() > retryMax) {
|
||||
throw new ExcessiveAttemptsException("您已连续错误达" + retryMax + "次!请10分钟后再试");
|
||||
}
|
||||
|
||||
boolean matches = super.doCredentialsMatch(token, info);
|
||||
if(matches) {
|
||||
passwordRetryCache.remove(username);
|
||||
}else {
|
||||
throw new IncorrectCredentialsException("密码错误,已错误" + retryCount.get() + "次,最多错误" + retryMax + "次");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getRetryMax() {
|
||||
return retryMax;
|
||||
}
|
||||
|
||||
public void setRetryMax(int retryMax) {
|
||||
this.retryMax = retryMax;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.apache.shiro.authc.credential.CredentialsMatcher;
|
||||
import org.apache.shiro.cache.CacheManager;
|
||||
import org.apache.shiro.cache.ehcache.EhCacheManager;
|
||||
import org.apache.shiro.crypto.CipherService;
|
||||
import org.apache.shiro.io.Serializer;
|
||||
import org.apache.shiro.mgt.RememberMeManager;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.realm.AuthenticatingRealm;
|
||||
import org.apache.shiro.realm.Realm;
|
||||
import org.apache.shiro.realm.jdbc.JdbcRealm;
|
||||
import org.apache.shiro.session.SessionListener;
|
||||
import org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler;
|
||||
import org.apache.shiro.session.mgt.SessionValidationScheduler;
|
||||
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
|
||||
import org.apache.shiro.session.mgt.eis.SessionDAO;
|
||||
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
|
||||
import org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
|
||||
import org.apache.shiro.web.mgt.CookieRememberMeManager;
|
||||
import org.apache.shiro.web.servlet.Cookie;
|
||||
import org.apache.shiro.web.servlet.SimpleCookie;
|
||||
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||
import org.apache.shiro.web.session.mgt.WebSessionManager;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.context.embedded.FilterRegistrationBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import com.xinwei.spring.boot.autoconfigure.shiro.annotation.EnableShiroWebSupport;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This guy is lazy, nothing left.
|
||||
*
|
||||
* @author John Zhang
|
||||
*/
|
||||
@Configuration
|
||||
@EnableShiroWebSupport
|
||||
@ConditionalOnWebApplication
|
||||
@Import(ShiroConfiguration.class)
|
||||
@EnableConfigurationProperties({
|
||||
ShiroProperties.class, ShiroSignInProperties.class,
|
||||
ShiroCookieProperties.class, ShiroSessionProperties.class,
|
||||
ShiroJdbcRealmProperties.class
|
||||
})
|
||||
public class ShiroAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ShiroProperties properties;
|
||||
|
||||
@Autowired
|
||||
private ShiroSignInProperties signInProperties;
|
||||
|
||||
@Autowired
|
||||
private ShiroCookieProperties shiroCookieProperties;
|
||||
|
||||
@Autowired
|
||||
private ShiroSessionProperties shiroSessionProperties;
|
||||
|
||||
@Autowired
|
||||
private ShiroJdbcRealmProperties shiroJdbcRealmProperties;
|
||||
|
||||
@Autowired(required = false)
|
||||
private CipherService cipherService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private Serializer<PrincipalCollection> serializer;
|
||||
|
||||
@Autowired(required = false)
|
||||
private Collection<SessionListener> listeners;
|
||||
|
||||
@Bean(name = "mainRealm")
|
||||
@ConditionalOnMissingBean(name = "mainRealm")
|
||||
@ConditionalOnProperty(prefix = "shiro.realm.jdbc", name = "enabled", havingValue = "true")
|
||||
@DependsOn(value = {"dataSource", "lifecycleBeanPostProcessor", "credentialsMatcher"})
|
||||
public Realm jdbcRealm(DataSource dataSource, CredentialsMatcher credentialsMatcher) {
|
||||
JdbcRealm jdbcRealm = new JdbcRealm();
|
||||
if (shiroJdbcRealmProperties.getAuthenticationQuery() != null) {
|
||||
jdbcRealm.setAuthenticationQuery(shiroJdbcRealmProperties.getAuthenticationQuery());
|
||||
}
|
||||
if (shiroJdbcRealmProperties.getUserRolesQuery() != null) {
|
||||
jdbcRealm.setUserRolesQuery(shiroJdbcRealmProperties.getUserRolesQuery());
|
||||
}
|
||||
if (shiroJdbcRealmProperties.getPermissionsQuery() != null) {
|
||||
jdbcRealm.setPermissionsQuery(shiroJdbcRealmProperties.getPermissionsQuery());
|
||||
}
|
||||
if (shiroJdbcRealmProperties.getSalt() != null) {
|
||||
jdbcRealm.setSaltStyle(shiroJdbcRealmProperties.getSalt());
|
||||
}
|
||||
jdbcRealm.setDataSource(dataSource);
|
||||
jdbcRealm.setCredentialsMatcher(credentialsMatcher);
|
||||
return jdbcRealm;
|
||||
}
|
||||
|
||||
@Bean(name = "mainRealm")
|
||||
@ConditionalOnMissingBean(name = "mainRealm")
|
||||
@DependsOn(value = {"lifecycleBeanPostProcessor", "credentialsMatcher"})
|
||||
public Realm realm(CredentialsMatcher credentialsMatcher) {
|
||||
Class<?> realmClass = properties.getRealmClass();
|
||||
Realm realm = (Realm) BeanUtils.instantiate(realmClass);
|
||||
if (realm instanceof AuthenticatingRealm) {
|
||||
((AuthenticatingRealm) realm).setCredentialsMatcher(credentialsMatcher);
|
||||
}
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Bean(name = "shiroCacheManager")
|
||||
@ConditionalOnClass(name = {"org.apache.shiro.cache.ehcache.EhCacheManager"})
|
||||
@ConditionalOnMissingBean(name = "shiroCacheManager")
|
||||
public CacheManager ehcacheManager() {
|
||||
EhCacheManager ehCacheManager = new EhCacheManager();
|
||||
ShiroProperties.Ehcache ehcache = properties.getEhcache();
|
||||
if (ehcache.getCacheManagerConfigFile() != null) {
|
||||
ehCacheManager.setCacheManagerConfigFile(ehcache.getCacheManagerConfigFile());
|
||||
}
|
||||
return ehCacheManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(Cookie.class)
|
||||
public Cookie rememberMeCookie() {
|
||||
SimpleCookie rememberMeCookie = new SimpleCookie();
|
||||
rememberMeCookie.setName(signInProperties.getRememberMeParam());
|
||||
rememberMeCookie.setMaxAge(shiroCookieProperties.getMaxAge());
|
||||
rememberMeCookie.setValue(shiroCookieProperties.getValue());
|
||||
rememberMeCookie.setVersion(shiroCookieProperties.getVersion());
|
||||
rememberMeCookie.setHttpOnly(shiroCookieProperties.isHttpOnly());
|
||||
rememberMeCookie.setSecure(shiroCookieProperties.isSecure());
|
||||
return rememberMeCookie;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(RememberMeManager.class)
|
||||
public RememberMeManager rememberMeManager(Cookie cookie) {
|
||||
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
|
||||
cookieRememberMeManager.setCookie(cookie);
|
||||
cookieRememberMeManager.setCipherService(cipherService);
|
||||
if (shiroCookieProperties.getCipherKey() != null) {
|
||||
cookieRememberMeManager.setCipherKey(shiroCookieProperties.getCipherKey().getBytes());
|
||||
} else {
|
||||
if (shiroCookieProperties.getEncryptionCipherKey() != null) {
|
||||
cookieRememberMeManager.setEncryptionCipherKey(shiroCookieProperties.getEncryptionCipherKey().getBytes());
|
||||
}
|
||||
if (shiroCookieProperties.getDecryptionCipherKey() != null) {
|
||||
cookieRememberMeManager.setDecryptionCipherKey(shiroCookieProperties.getDecryptionCipherKey().getBytes());
|
||||
}
|
||||
}
|
||||
cookieRememberMeManager.setSerializer(serializer);
|
||||
return cookieRememberMeManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SessionDAO sessionDAO(CacheManager cacheManager) {
|
||||
EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO();
|
||||
sessionDAO.setActiveSessionsCacheName(shiroSessionProperties.getActiveSessionsCacheName());
|
||||
Class<? extends SessionIdGenerator> idGenerator = shiroSessionProperties.getIdGenerator();
|
||||
if (idGenerator != null) {
|
||||
SessionIdGenerator sessionIdGenerator = BeanUtils.instantiate(idGenerator);
|
||||
sessionDAO.setSessionIdGenerator(sessionIdGenerator);
|
||||
}
|
||||
sessionDAO.setCacheManager(cacheManager);
|
||||
return sessionDAO;
|
||||
}
|
||||
|
||||
@Bean(name = "sessionValidationScheduler")
|
||||
@DependsOn(value = {"sessionManager"})
|
||||
@ConditionalOnClass(name = {"org.quartz.Scheduler"})
|
||||
@ConditionalOnMissingBean(SessionValidationScheduler.class)
|
||||
public SessionValidationScheduler quartzSessionValidationScheduler(DefaultWebSessionManager sessionManager) {
|
||||
QuartzSessionValidationScheduler quartzSessionValidationScheduler = new QuartzSessionValidationScheduler(sessionManager);
|
||||
quartzSessionValidationScheduler.setSessionValidationInterval(shiroSessionProperties.getValidationInterval());
|
||||
quartzSessionValidationScheduler.enableSessionValidation();
|
||||
sessionManager.setDeleteInvalidSessions(shiroSessionProperties.isDeleteInvalidSessions());
|
||||
sessionManager.setSessionValidationInterval(shiroSessionProperties.getValidationInterval());
|
||||
sessionManager.setSessionValidationSchedulerEnabled(shiroSessionProperties.isValidationSchedulerEnabled());
|
||||
sessionManager.setSessionValidationScheduler(quartzSessionValidationScheduler);
|
||||
return quartzSessionValidationScheduler;
|
||||
}
|
||||
|
||||
@Bean(name = "sessionValidationScheduler")
|
||||
@DependsOn(value = {"sessionManager"})
|
||||
@ConditionalOnMissingBean(SessionValidationScheduler.class)
|
||||
public SessionValidationScheduler sessionValidationScheduler(DefaultWebSessionManager sessionManager) {
|
||||
ExecutorServiceSessionValidationScheduler validationScheduler = new ExecutorServiceSessionValidationScheduler(sessionManager);
|
||||
sessionManager.setDeleteInvalidSessions(shiroSessionProperties.isDeleteInvalidSessions());
|
||||
sessionManager.setSessionValidationInterval(shiroSessionProperties.getValidationInterval());
|
||||
sessionManager.setSessionValidationSchedulerEnabled(shiroSessionProperties.isValidationSchedulerEnabled());
|
||||
sessionManager.setSessionValidationScheduler(validationScheduler);
|
||||
return validationScheduler;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@DependsOn(value = {"shiroCacheManager", "sessionDAO"})
|
||||
public WebSessionManager sessionManager(CacheManager cacheManager, SessionDAO sessionDAO) {
|
||||
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
|
||||
sessionManager.setCacheManager(cacheManager);
|
||||
sessionManager.setGlobalSessionTimeout(shiroSessionProperties.getGlobalSessionTimeout());
|
||||
|
||||
sessionManager.setSessionDAO(sessionDAO);
|
||||
sessionManager.setSessionListeners(listeners);
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
@Bean(name = "credentialsMatcher")
|
||||
@ConditionalOnMissingBean
|
||||
@DependsOn("shiroCacheManager")
|
||||
public CredentialsMatcher credentialsMatcher(CacheManager cacheManager) {
|
||||
RetryLimitHashedCredentialsMatcher credentialsMatcher = new RetryLimitHashedCredentialsMatcher(cacheManager);
|
||||
credentialsMatcher.setHashAlgorithmName(properties.getHashAlgorithmName());
|
||||
credentialsMatcher.setHashIterations(properties.getHashIterations());
|
||||
credentialsMatcher.setStoredCredentialsHexEncoded(properties.isStoredCredentialsHexEncoded());
|
||||
credentialsMatcher.setRetryMax(properties.getRetryMax());
|
||||
return credentialsMatcher;
|
||||
}
|
||||
|
||||
public FormSignInFilter formSignInFilter() {
|
||||
FormSignInFilter filter = new FormSignInFilter();
|
||||
filter.setLoginUrl(properties.getLoginUrl());
|
||||
filter.setSuccessUrl(properties.getSuccessUrl());
|
||||
filter.setUsernameParam(signInProperties.getUserParam());
|
||||
filter.setPasswordParam(signInProperties.getPasswordParam());
|
||||
filter.setRememberMeParam(signInProperties.getRememberMeParam());
|
||||
return filter;
|
||||
}
|
||||
|
||||
public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager) {
|
||||
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
|
||||
shiroFilter.setSecurityManager(securityManager);
|
||||
shiroFilter.setLoginUrl(properties.getLoginUrl());
|
||||
shiroFilter.setSuccessUrl(properties.getSuccessUrl());
|
||||
shiroFilter.setUnauthorizedUrl(properties.getUnauthorizedUrl());
|
||||
|
||||
Map<String, Filter> filterMap = new LinkedHashMap<String, Filter>();
|
||||
Class<? extends AuthorizationFilter> customAuthcFilterClass = properties.getCustomAuthcFilterClass();
|
||||
if (null != customAuthcFilterClass ) {
|
||||
AuthorizationFilter filter = BeanUtils.instantiate(customAuthcFilterClass);
|
||||
filterMap.put("authc", filter);
|
||||
} else {
|
||||
filterMap.put("authc", formSignInFilter());
|
||||
}
|
||||
|
||||
shiroFilter.setFilters(filterMap);
|
||||
shiroFilter.setFilterChainDefinitionMap(properties.getFilterChainDefinitions());
|
||||
return shiroFilter;
|
||||
}
|
||||
|
||||
@Bean(name = "shiroFilter")
|
||||
@DependsOn("securityManager")
|
||||
@ConditionalOnMissingBean
|
||||
public FilterRegistrationBean filterRegistrationBean(SecurityManager securityManager) throws Exception {
|
||||
FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
|
||||
//该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
|
||||
filterRegistration.addInitParameter("targetFilterLifecycle", "true");
|
||||
filterRegistration.setFilter((Filter) getShiroFilterFactoryBean(securityManager).getObject());
|
||||
filterRegistration.setEnabled(true);
|
||||
filterRegistration.addUrlPatterns("/*");
|
||||
return filterRegistration;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.apache.shiro.cache.CacheManager;
|
||||
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
|
||||
import org.apache.shiro.cache.ehcache.EhCacheManager;
|
||||
import org.apache.shiro.mgt.DefaultSecurityManager;
|
||||
import org.apache.shiro.mgt.RememberMeManager;
|
||||
import org.apache.shiro.realm.Realm;
|
||||
import org.apache.shiro.session.mgt.SessionManager;
|
||||
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
/**
|
||||
* This guy is lazy, nothing left.
|
||||
*
|
||||
* @author John Zhang
|
||||
*/
|
||||
public class ShiroConfiguration {
|
||||
|
||||
@Bean(name = "lifecycleBeanPostProcessor")
|
||||
@ConditionalOnMissingBean
|
||||
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
|
||||
return new LifecycleBeanPostProcessor();
|
||||
}
|
||||
|
||||
@ConditionalOnMissingBean
|
||||
@Bean(name = "defaultAdvisorAutoProxyCreator")
|
||||
@DependsOn("lifecycleBeanPostProcessor")
|
||||
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
|
||||
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
|
||||
return defaultAdvisorAutoProxyCreator;
|
||||
}
|
||||
|
||||
/**
|
||||
* (基于内存的)用户授权信息Cache
|
||||
*/
|
||||
@Bean(name = "shiroCacheManager")
|
||||
@ConditionalOnMissingBean(name = "shiroCacheManager")
|
||||
@ConditionalOnMissingClass(value = {"org.apache.shiro.cache.ehcache.EhCacheManager"})
|
||||
public CacheManager shiroCacheManager() {
|
||||
return new MemoryConstrainedCacheManager();
|
||||
}
|
||||
|
||||
@Bean(name = "securityManager")
|
||||
@DependsOn(value = {"shiroCacheManager", "rememberMeManager", "mainRealm"})
|
||||
public DefaultSecurityManager securityManager(Realm realm, RememberMeManager rememberMeManager,
|
||||
CacheManager cacheManager, SessionManager sessionManager) {
|
||||
DefaultSecurityManager sm = new DefaultWebSecurityManager();
|
||||
sm.setRealm(realm);
|
||||
sm.setCacheManager(cacheManager);
|
||||
sm.setSessionManager(sessionManager);
|
||||
sm.setRememberMeManager(rememberMeManager);
|
||||
return sm;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultSecurityManager securityManager) {
|
||||
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
|
||||
aasa.setSecurityManager(securityManager);
|
||||
return aasa;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* This guy is lazy, nothing left.
|
||||
*
|
||||
* @author John Zhang
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "shiro.cookie")
|
||||
public class ShiroCookieProperties {
|
||||
|
||||
private String name = "rememberMe";
|
||||
|
||||
private String value;
|
||||
|
||||
private int maxAge = 60 * 60 * 24 * 365; // one year
|
||||
|
||||
private int version = -1;
|
||||
|
||||
private boolean secure;
|
||||
|
||||
private boolean httpOnly = true;
|
||||
|
||||
private String cipherKey;
|
||||
|
||||
private String encryptionCipherKey;
|
||||
|
||||
private String decryptionCipherKey;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getMaxAge() {
|
||||
return maxAge;
|
||||
}
|
||||
|
||||
public void setMaxAge(int maxAge) {
|
||||
this.maxAge = maxAge;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
return secure;
|
||||
}
|
||||
|
||||
public void setSecure(boolean secure) {
|
||||
this.secure = secure;
|
||||
}
|
||||
|
||||
public boolean isHttpOnly() {
|
||||
return httpOnly;
|
||||
}
|
||||
|
||||
public void setHttpOnly(boolean httpOnly) {
|
||||
this.httpOnly = httpOnly;
|
||||
}
|
||||
|
||||
public String getCipherKey() {
|
||||
return cipherKey;
|
||||
}
|
||||
|
||||
public void setCipherKey(String cipherKey) {
|
||||
this.cipherKey = cipherKey;
|
||||
}
|
||||
|
||||
public String getEncryptionCipherKey() {
|
||||
return encryptionCipherKey;
|
||||
}
|
||||
|
||||
public void setEncryptionCipherKey(String encryptionCipherKey) {
|
||||
this.encryptionCipherKey = encryptionCipherKey;
|
||||
}
|
||||
|
||||
public String getDecryptionCipherKey() {
|
||||
return decryptionCipherKey;
|
||||
}
|
||||
|
||||
public void setDecryptionCipherKey(String decryptionCipherKey) {
|
||||
this.decryptionCipherKey = decryptionCipherKey;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.apache.shiro.realm.jdbc.JdbcRealm;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* This guy is lazy, nothing left.
|
||||
*
|
||||
* @author John Zhang
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "shiro.realm.jdbc")
|
||||
public class ShiroJdbcRealmProperties {
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
private JdbcRealm.SaltStyle salt;
|
||||
|
||||
/**
|
||||
* select password from users where username = ?
|
||||
*/
|
||||
private String authenticationQuery;
|
||||
|
||||
/**
|
||||
* select role_name from user_roles where username = ?
|
||||
*/
|
||||
private String userRolesQuery;
|
||||
|
||||
/**
|
||||
* select permission from roles_permissions where role_name = ?
|
||||
*/
|
||||
private String permissionsQuery;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getAuthenticationQuery() {
|
||||
return authenticationQuery;
|
||||
}
|
||||
|
||||
public void setAuthenticationQuery(String authenticationQuery) {
|
||||
this.authenticationQuery = authenticationQuery;
|
||||
}
|
||||
|
||||
public String getUserRolesQuery() {
|
||||
return userRolesQuery;
|
||||
}
|
||||
|
||||
public void setUserRolesQuery(String userRolesQuery) {
|
||||
this.userRolesQuery = userRolesQuery;
|
||||
}
|
||||
|
||||
public String getPermissionsQuery() {
|
||||
return permissionsQuery;
|
||||
}
|
||||
|
||||
public void setPermissionsQuery(String permissionsQuery) {
|
||||
this.permissionsQuery = permissionsQuery;
|
||||
}
|
||||
|
||||
public JdbcRealm.SaltStyle getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public void setSalt(JdbcRealm.SaltStyle salt) {
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.apache.shiro.realm.Realm;
|
||||
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Configuration properties for Shiro.
|
||||
*
|
||||
* @author John Zhang
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "shiro")
|
||||
public class ShiroProperties {
|
||||
/**
|
||||
* Custom Realm
|
||||
*/
|
||||
private Class<? extends Realm> realmClass = null;
|
||||
|
||||
/**
|
||||
* URL of login
|
||||
*/
|
||||
private String loginUrl = "/login";
|
||||
/**
|
||||
* URL of success
|
||||
*/
|
||||
private String successUrl = "/index";
|
||||
/**
|
||||
* URL of unauthorized
|
||||
*/
|
||||
private String unauthorizedUrl = "/unauthorized";
|
||||
|
||||
private String hashAlgorithmName = "MD5";
|
||||
|
||||
private int hashIterations = 1;
|
||||
|
||||
/**
|
||||
* 密码重试次数上限
|
||||
*/
|
||||
private int retryMax = 100;
|
||||
|
||||
private boolean storedCredentialsHexEncoded = true;
|
||||
|
||||
/**
|
||||
* Filter chain
|
||||
*/
|
||||
private Map<String, String> filterChainDefinitions;
|
||||
|
||||
private final Ehcache ehcache = new Ehcache();
|
||||
|
||||
/**
|
||||
* Custom Realm
|
||||
*/
|
||||
private Class<? extends AuthorizationFilter> customAuthcFilterClass = null;
|
||||
|
||||
public Class<? extends Realm> getRealmClass() {
|
||||
return realmClass;
|
||||
}
|
||||
|
||||
public void setRealmClass(Class<? extends Realm> realmClass) {
|
||||
this.realmClass = realmClass;
|
||||
}
|
||||
|
||||
public String getLoginUrl() {
|
||||
return loginUrl;
|
||||
}
|
||||
|
||||
public void setLoginUrl(String loginUrl) {
|
||||
this.loginUrl = loginUrl;
|
||||
}
|
||||
|
||||
public String getSuccessUrl() {
|
||||
return successUrl;
|
||||
}
|
||||
|
||||
public void setSuccessUrl(String successUrl) {
|
||||
this.successUrl = successUrl;
|
||||
}
|
||||
|
||||
public String getUnauthorizedUrl() {
|
||||
return unauthorizedUrl;
|
||||
}
|
||||
|
||||
public void setUnauthorizedUrl(String unauthorizedUrl) {
|
||||
this.unauthorizedUrl = unauthorizedUrl;
|
||||
}
|
||||
|
||||
public String getHashAlgorithmName() {
|
||||
return hashAlgorithmName;
|
||||
}
|
||||
|
||||
public void setHashAlgorithmName(String hashAlgorithmName) {
|
||||
this.hashAlgorithmName = hashAlgorithmName;
|
||||
}
|
||||
|
||||
public int getHashIterations() {
|
||||
return hashIterations;
|
||||
}
|
||||
|
||||
public void setHashIterations(int hashIterations) {
|
||||
this.hashIterations = hashIterations;
|
||||
}
|
||||
|
||||
public int getRetryMax() {
|
||||
return retryMax;
|
||||
}
|
||||
|
||||
public void setRetryMax(int retryMax) {
|
||||
this.retryMax = retryMax;
|
||||
}
|
||||
|
||||
public boolean isStoredCredentialsHexEncoded() {
|
||||
return storedCredentialsHexEncoded;
|
||||
}
|
||||
|
||||
public void setStoredCredentialsHexEncoded(boolean storedCredentialsHexEncoded) {
|
||||
this.storedCredentialsHexEncoded = storedCredentialsHexEncoded;
|
||||
}
|
||||
|
||||
public Map<String, String> getFilterChainDefinitions() {
|
||||
return filterChainDefinitions;
|
||||
}
|
||||
|
||||
public void setFilterChainDefinitions(Map<String, String> filterChainDefinitions) {
|
||||
this.filterChainDefinitions = filterChainDefinitions;
|
||||
}
|
||||
|
||||
public Ehcache getEhcache() {
|
||||
return ehcache;
|
||||
}
|
||||
|
||||
public Class<? extends AuthorizationFilter> getCustomAuthcFilterClass() {
|
||||
return customAuthcFilterClass;
|
||||
}
|
||||
|
||||
public void setCustomAuthcFilterClass(Class<? extends AuthorizationFilter> customAuthcFilterClass) {
|
||||
this.customAuthcFilterClass = customAuthcFilterClass;
|
||||
}
|
||||
|
||||
public static class Ehcache {
|
||||
|
||||
private String cacheManagerConfigFile = "classpath:org/apache/shiro/cache/ehcache/ehcache.xml";
|
||||
|
||||
public String getCacheManagerConfigFile() {
|
||||
return cacheManagerConfigFile;
|
||||
}
|
||||
|
||||
public void setCacheManagerConfigFile(String cacheManagerConfigFile) {
|
||||
this.cacheManagerConfigFile = cacheManagerConfigFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
|
||||
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* This guy is lazy, nothing left.
|
||||
*
|
||||
* @author John Zhang
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "shiro.session")
|
||||
public class ShiroSessionProperties {
|
||||
|
||||
private long globalSessionTimeout = 30 * 60 * 1000L;
|
||||
|
||||
private boolean deleteInvalidSessions = true;
|
||||
|
||||
private long validationInterval = 60 * 60 * 1000L;
|
||||
|
||||
private boolean validationSchedulerEnabled = true;
|
||||
|
||||
private String activeSessionsCacheName = "shiro-activeSessionCache";
|
||||
|
||||
private Class<? extends SessionIdGenerator> idGenerator = JavaUuidSessionIdGenerator.class;
|
||||
|
||||
public long getGlobalSessionTimeout() {
|
||||
return globalSessionTimeout;
|
||||
}
|
||||
|
||||
public void setGlobalSessionTimeout(long globalSessionTimeout) {
|
||||
this.globalSessionTimeout = globalSessionTimeout;
|
||||
}
|
||||
|
||||
public boolean isDeleteInvalidSessions() {
|
||||
return deleteInvalidSessions;
|
||||
}
|
||||
|
||||
public void setDeleteInvalidSessions(boolean deleteInvalidSessions) {
|
||||
this.deleteInvalidSessions = deleteInvalidSessions;
|
||||
}
|
||||
|
||||
public long getValidationInterval() {
|
||||
return validationInterval;
|
||||
}
|
||||
|
||||
public void setValidationInterval(long validationInterval) {
|
||||
this.validationInterval = validationInterval;
|
||||
}
|
||||
|
||||
public boolean isValidationSchedulerEnabled() {
|
||||
return validationSchedulerEnabled;
|
||||
}
|
||||
|
||||
public void setValidationSchedulerEnabled(boolean validationSchedulerEnabled) {
|
||||
this.validationSchedulerEnabled = validationSchedulerEnabled;
|
||||
}
|
||||
|
||||
public String getActiveSessionsCacheName() {
|
||||
return activeSessionsCacheName;
|
||||
}
|
||||
|
||||
public void setActiveSessionsCacheName(String activeSessionsCacheName) {
|
||||
this.activeSessionsCacheName = activeSessionsCacheName;
|
||||
}
|
||||
|
||||
public Class<? extends SessionIdGenerator> getIdGenerator() {
|
||||
return idGenerator;
|
||||
}
|
||||
|
||||
public void setIdGenerator(Class<? extends SessionIdGenerator> idGenerator) {
|
||||
this.idGenerator = idGenerator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for Shiro FormAuthenticationFilter
|
||||
*
|
||||
* @author John Zhang
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "shiro.sign-in")
|
||||
public class ShiroSignInProperties {
|
||||
/**
|
||||
* Request parameter's name of user
|
||||
*/
|
||||
private String userParam = "username";
|
||||
|
||||
/**
|
||||
* Request parameter's name of password
|
||||
*/
|
||||
private String passwordParam = "password";
|
||||
|
||||
private String rememberMeParam = "rememberMe";
|
||||
|
||||
public String getUserParam() {
|
||||
return userParam;
|
||||
}
|
||||
|
||||
public void setUserParam(String userParam) {
|
||||
this.userParam = userParam;
|
||||
}
|
||||
|
||||
public String getPasswordParam() {
|
||||
return passwordParam;
|
||||
}
|
||||
|
||||
public void setPasswordParam(String passwordParam) {
|
||||
this.passwordParam = passwordParam;
|
||||
}
|
||||
|
||||
public String getRememberMeParam() {
|
||||
return rememberMeParam;
|
||||
}
|
||||
|
||||
public void setRememberMeParam(String rememberMeParam) {
|
||||
this.rememberMeParam = rememberMeParam;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
import com.xinwei.spring.boot.autoconfigure.shiro.annotation.SessionUserArgumentResolver;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This guy is lazy, nothing left.
|
||||
*
|
||||
* @author John Zhang
|
||||
*/
|
||||
@Configuration
|
||||
public class ShiroWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(new SessionUserArgumentResolver());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import com.xinwei.spring.boot.autoconfigure.shiro.ShiroWebMvcConfigurerAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* Annotation to automatically register the following beans for usage with Spring MVC.
|
||||
* <ul>
|
||||
* <li>
|
||||
* {@link com.xinwei.spring.boot.autoconfigure.shiro.annotation.SessionUser}.
|
||||
* </li>
|
||||
* </ul>
|
||||
* @author John Zhang
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
|
||||
@Inherited
|
||||
@Import({ EnableShiroWebSupport.ShiroWebMvcConfigurerAdapterImportSelector.class })
|
||||
public @interface EnableShiroWebSupport {
|
||||
|
||||
static class ShiroWebMvcConfigurerAdapterImportSelector implements ImportSelector {
|
||||
|
||||
@Override
|
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
return new String[] { ShiroWebMvcConfigurerAdapter.class.getName() };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 获取Shiro当前用户
|
||||
* @author 张劲航
|
||||
* @see SessionUserArgumentResolver
|
||||
*/
|
||||
@Target({ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SessionUser {
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.xinwei.spring.boot.autoconfigure.shiro.annotation;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
* {@link SessionUser}注解的解析
|
||||
* @author 张劲航
|
||||
*/
|
||||
public class SessionUserArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return parameter.hasParameterAnnotation(SessionUser.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
if(supportsParameter(parameter) && subject.isAuthenticated()){
|
||||
return subject.getPrincipal();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user