Shiro 是一个 java 的安全框架,相比 Spring Security 更加轻量,可以很方便的完成认证、授权、加密、会话管理、缓存等功能.
将 shiro 相关的 jar 包引入 pom.xml
<dependency>
<groupId>org.apache.shiro</ groupId>
<artifactId>shiro-core</ artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</ groupId>
<artifactId>shiro-spring</ artifactId>
<version>1.3.2</version>
</dependency>
shiro-spring 用于将 shiro 与 spring 进行集成
在 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>
</filter-mapping>
targetFilterLifecycle 说明:
默认情况下,filter 在 bean 之前加载,导致 filter 中获取到的 bean 为空
DelegatingFilterProxy 是一个代理类,用于将请求委派给与 filter-name 一致的 bean 进行处理,该 bean 实现了 Filter 接口
targetFilterLifecycle 设置为 true,可以实现由 spring 管理 filter bean (默认由 tomcat 容器进行管理)
在 spring 配置文件中加入
<bean id=”shiroFilter” class=”org.apache.shiro.spring.web.ShiroFilterFactoryBean”>
<property name=”securityManager” ref=”securityManager” />
<property name=”loginUrl” ref=”/login” />
<property name=”successUrl” ref=”/main” />
<property name=”unauthorizedUrl” ref=”/unauthorized” />
<property name=”filters”>
<map>
<entry key=”anyRoles” value-ref=”anyRolesAuthorizationFilter” />
</map>
</ property>
<property name=”filterChainDefinitions”>
<value>
/login = anon
/main = authc, anyRoles[superadmin, company]
/logout = logout
</value>
</property>
</bean>
<!--自定义过滤器 -->
<bean id=”anyRolesAuthorizationFilter” class=”com.xxx.AnyRolesAuthorizationFilter”/>
<!--自定义 Realm (安全数据源): 用于认证及授权 -->
<bean id=”myRealm” class=”com.xxx.MyRealm” />
<!-- 用户授权信息 Cache -->
<bean id=”cacheManager” class=”org.apache.shiro.cache.MemoryConstrainedCacheManager” />
<!-- 安全管理器 -->
<bean id=”securityManager” class=”org.apache.shiro.web.mgt.DefaultWebSecurityManager”>
<propery name=”ream” ref=”myRealm”></propery>
<propery name=”cacheManager” ref=”cacheManager”></propery>
</bean>
anyRoles 为自定义 shiro 过滤器(继承 AuthorizationFilter 类):
public class AnyRolesAuthorizationFilter extends AuthorizationFilter {
@Override
protected boolean isAccessAllowed(
ServletRequest request,
ServletResponse response,
Object mappedValue) throws Exception {
Subject subject = getSubject(request, response);
String[] rolesArray = (String[]) mappedValue;
if (rolesArray == null || rolesArray.length == 0) {
return true;
}
Set<String> roles = CollectionUtils.asSet(rolesArray);
for (String role: roles) {
if (subject.hasRole(role)) {
return true;
}
}
return false;
}
}
myRealm 如下:
public class MyRealm extends AuthorizingRealm {
/**
* 认证回调方法 (登录时调用)
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken at) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) at;
String username = token.getUsername();
String password = String.valueOf(token.getPassword());
return new SimpleAuthenticationInfo(username, password, getName());
}
/**
* 授权回调方法 (进行授权但缓存中无用户的授权信息时调用, 在配有缓存的情况下, 只调用一次)
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Set<String> roleSet = new HashSet<>();
Set<String> permissionSet = new HashSet<>();
String username = (String) pc.getPrimaryPrincipal();
if (username != null) {
Set<Role> roles = getRoles(username);
for (Role r : roles) {
roleSet.add(r.getCode());
for (Permission p : r.getPermissionSet()) {
permissionSet.add(p.getCode());
}
}
info.addRoles(roleSet);
info.addStringPermissions(permissionSet);
}
return info;
}
private Set<Role> getRoles(String username) {
// 通过 username 获取角色
}
}
shiro 默认过滤器:
anon: 代表不需要授权即可访问(对于静态资源,访问权限都设置为 anon)
authc: 需要登录才能访问
roles:需要同时有拥有相应角色才能访问(多个角色用逗号分隔)
perms:需要同时拥有相应权限才能访问(多个权限用逗号分隔,若有多个则需要加引号)
logout:清除缓存、删除会话
shiro 的 JSP 标签:
<shiro:authenticated> 登录成功
<shiro:notAuthenticated>未登录
<shiro:hasAnyRoles name="admin,xxx"> 在有 admin 或者 xxx 角色时
<shiro:hasRole name="xxx"> 拥有角色 xxx
<shiro:lacksRole name="xxx"> 没有角色 xxx
<shiro:hasPermission name="xxx"> 拥有权限 xxx
<shiro:lacksPermission name="xxx"> 没有权限 xxx
<shiro:principal> 显示用户登录名
在使用标签前,先在 jsp 页面中引入
<%@ taglib prefix=”shiro” uri=”http://shiro.apache.org/tags” %>
留言与评论(共有 0 条评论) |