1.web.xml文件的配置
<!--Shiro过滤器 -->
<filter><filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
2.applicationContext-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
default-lazy-init="true">
<description>Shiro Configuration</description>
<!--安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="shiroDbRealm"/>
<property name="cacheManager" ref="cacheManager"/>
<!-- <property name="sessionManager" ref="sessionManager"/> -->
</bean>
<!-- 項目自定义的Realm -->
<bean id="shiroDbRealm" class="com.huaxia.security.shiro.ShiroDbRealm"/> // 自己写的域
<!-- Shiro Filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login"/>
<property name="successUrl" value="/index"/>
<property name="unauthorizedUrl" value="/unauth"/>
<property name="filterChainDefinitions">
<value>
/commons/** = anon
/plugins/** = anon
/assets/** = anon
/css/** = anon
/js/** = anon
/img/** = anon
/fonts/** = anon
/bootstrap/** = anon
/login = anon
/interface/** = anon
/** = user
</value>
</property>
</bean>
<!-- 用户授权信息Cache -->
<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
<!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="#{30 * 60 * 1000}"/>
<property name="sessionIdUrlRewritingEnabled" value="false"/>
</bean>
<!-- 在方法中 注入 securityManager ,进行代理控制 -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
<property name="arguments" ref="securityManager"/>
</bean>
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- AOP式方法级权限检查 -->
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="false" />
</bean>
<!-- 启用shrio授权注解拦截方式 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
default-lazy-init="true">
<description>Shiro Configuration</description>
<!--安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="shiroDbRealm"/>
<property name="cacheManager" ref="cacheManager"/>
<!-- <property name="sessionManager" ref="sessionManager"/> -->
</bean>
<!-- 項目自定义的Realm -->
<bean id="shiroDbRealm" class="com.huaxia.security.shiro.ShiroDbRealm"/> // 自己写的域
<!-- Shiro Filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login"/>
<property name="successUrl" value="/index"/>
<property name="unauthorizedUrl" value="/unauth"/>
<property name="filterChainDefinitions">
<value>
/commons/** = anon
/plugins/** = anon
/assets/** = anon
/css/** = anon
/js/** = anon
/img/** = anon
/fonts/** = anon
/bootstrap/** = anon
/login = anon
/interface/** = anon
/** = user
</value>
</property>
</bean>
<!-- 用户授权信息Cache -->
<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
<!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="#{30 * 60 * 1000}"/>
<property name="sessionIdUrlRewritingEnabled" value="false"/>
</bean>
<!-- 在方法中 注入 securityManager ,进行代理控制 -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
<property name="arguments" ref="securityManager"/>
</bean>
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- AOP式方法级权限检查 -->
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="false" />
</bean>
<!-- 启用shrio授权注解拦截方式 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>
3. shiroUser
public class ShiroUser implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Long id;
private String username;
public ShiroUser(Long id, String username) {
super();
this.id = id;
this.username = username;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
/**
*
*/
private static final long serialVersionUID = 1L;
private Long id;
private String username;
public ShiroUser(Long id, String username) {
super();
this.id = id;
this.username = username;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
4. ShiroDbRealm
public class ShiroDbRealm extends AuthorizingRealm{
private static final Logger LOGGER = LogManager.getLogger(ShiroDbRealm.class);
@Autowired
private ILoginService loginService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
LOGGER.info("Shiro开始登录认证");
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
User un = loginService.selectByUsername(token.getUsername());
// 账号不存在
if (un == null) {
return null;
}
ShiroUser shiroUser = new ShiroUser(un.getId(), un.getUsername());
// 认证缓存信息
return new SimpleAuthenticationInfo(shiroUser, un.getPassword().toCharArray(), getName());
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
}
private static final Logger LOGGER = LogManager.getLogger(ShiroDbRealm.class);
@Autowired
private ILoginService loginService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
LOGGER.info("Shiro开始登录认证");
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
User un = loginService.selectByUsername(token.getUsername());
// 账号不存在
if (un == null) {
return null;
}
ShiroUser shiroUser = new ShiroUser(un.getId(), un.getUsername());
// 认证缓存信息
return new SimpleAuthenticationInfo(shiroUser, un.getPassword().toCharArray(), getName());
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
}
5.controller
@SystemControllerLog(operatePoint=OperatePointConstants.LOGIN, operateType=OperateTypeConstants.LOGIN)
@PostMapping("/login")
@CsrfToken(remove = true)
@ResponseBody
public Object loginPost(String username, String password) {
logger.info("POST请求登录");
if (StringUtils.isBlank(username)) {
return renderError("用户名不能为空");
}
if (StringUtils.isBlank(password)) {
return renderError("密码不能为空");
}else{
password = SymmetricEncoder.encryptStr(secretkey, password);
// LOGGER.info(password);
}
Subject user = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
Result result=new Result();
try {
user.login(token); //在这一步跳入入自己实现的域即shiroDbRealm中验证
return renderSuccess();
} catch (UnknownAccountException e) {
result.setMsg("账号不存在");
return result;
/*throw new RuntimeException("账号不存在!", e);*/
} catch (DisabledAccountException e) {
result.setMsg("账号未启用");
return result;
/*throw new RuntimeException("账号未启用", e);*/
} catch (IncorrectCredentialsException e) {
result.setMsg("密码错误,请重试");
return result;
/*throw new RuntimeException("密码错误,请重试", e);*/
} catch (Throwable e) {
result.setMsg("未知错误,请联系管理员");
return result;
// throw new RuntimeException("未知错误,请联系管理员", e);
}
}
@PostMapping("/login")
@CsrfToken(remove = true)
@ResponseBody
public Object loginPost(String username, String password) {
logger.info("POST请求登录");
if (StringUtils.isBlank(username)) {
return renderError("用户名不能为空");
}
if (StringUtils.isBlank(password)) {
return renderError("密码不能为空");
}else{
password = SymmetricEncoder.encryptStr(secretkey, password);
// LOGGER.info(password);
}
Subject user = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
Result result=new Result();
try {
user.login(token); //在这一步跳入入自己实现的域即shiroDbRealm中验证
return renderSuccess();
} catch (UnknownAccountException e) {
result.setMsg("账号不存在");
return result;
/*throw new RuntimeException("账号不存在!", e);*/
} catch (DisabledAccountException e) {
result.setMsg("账号未启用");
return result;
/*throw new RuntimeException("账号未启用", e);*/
} catch (IncorrectCredentialsException e) {
result.setMsg("密码错误,请重试");
return result;
/*throw new RuntimeException("密码错误,请重试", e);*/
} catch (Throwable e) {
result.setMsg("未知错误,请联系管理员");
return result;
// throw new RuntimeException("未知错误,请联系管理员", e);
}
}