Shiro安全框架使用
1.添加依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>${shiro.version}</version>
</dependency>
2.在web.xml配置文件中配置过滤器
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<bean id="shiroFilter"
class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login.html" />
<property name="successUrl" value="/index.html" />
<property name="unauthorizedUrl" value="/unauthorized.html" />
<property name="filterChainDefinitions">
<value>
/login.html* = anon
/user_login.action* = anon
/css/** = anon
/js/** = anon
/images/** = anon
/services/** = anon
/pages/base/courier.html* = perms[courier:list]
/pages/base/area.html* = roles[base]
/** = authc
</value>
</property>
</bean>
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="bosRealm" />
<property name="cacheManager" ref="shiroCacheManager" />
</bean>
<bean id="bosRealm" class="cn.itcast.bos.realm.BosRealm">
<property name="authorizationCacheName" value="bos" />
</bean>
<bean id="lifecycleBeanPostProcessor"
class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor" >
<property name="proxyTargetClass" value="true" />
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>
4.基于粗粒度的权限控制
@Action(value = "user_login", results = {
@Result(name = "index", type = "redirect", location = "index.html"),
@Result(name = "login", type = "redirect", location = "login.html")})
public String login(){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token =
new UsernamePasswordToken(model.getUsername(), model.getPassword());
try {
subject.login(token);
return "index";
} catch (Exception e) {
e.printStackTrace();
return "login";
}
}
@Service("bosService")
public class BosRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 认证
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
User user = userService.findByUsername(usernamePasswordToken.getUsername());
if(user == null){
return null;
}else {
/**
* 参数1: 期望登陆后保存在subject中的信息
* 参数2: 如果返回null, 说明用户不存在
* 参数3: realm名称
*/
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
}
}
}
5.基于细粒度(方法级别的)权限控制
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
/**
* 在Action类中的方法上添加注解:
* @RequiresAuthentication: 验证用户是否登陆.
* @RequiresUser: 判断用户是否被记忆.
* @RequiresGuest: 验证是否是一个guest请求.
* @RequiresRoles("","") 验证是否有需要的角色
* @RequiresPermissions("","") 验证是否有需要的权限
*/
@RequiresPermissions("courier_add")
@Action(value = "courier_save", results =
@Result(name = "success", type = "redirect", location = "./pages/base/courier.html"))
public String save() {
System.out.println("保存业务员");
courierService.save(courier);
return SUCCESS;
}
注意: 在service层添加的事务默认采用的是jdk的动态代理, 这里需要配置为cglib的动态代理
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true"/>
</bean>
6.基于自定义标签实现权限管理
<%@taglib uri="http://shiro.apache.org.tags" prefix="shiro"%>
<shiro:hasPermission name="courier:add">
<a href="#">添加</a>
</shiro:hasPermission>