参考:
http://kdboy.iteye.com/blog/1103794
http://blog.csdn.net/hxpjava1/article/details/7035724
http://blog.itpub.net/23071790/viewspace-709367/
http://www.infoq.com/cn/articles/apache-shiro
org.apache.shiro.spring.web.ShiroFilterFactoryBean DOC
在web.xml中配置Shiro的过滤器
<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> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping>
可以在<filter></filter>中加入targetFilterLifecycle
<init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param>
如果设置"targetFilterLifecycle"为true,则spring来管理Filter.init()和Filter.destroy();若为false,则这两个方法失效。
在Spring的配置文件中添加Shiro的过滤器
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value="/login" /> <property name="successUrl" value="/wellcome" /> <property name="unauthorizedUrl" value="/forbid" /> <property name="filterChainDefinitions"> <value> /login = authc /logout = logout /account/** = user /admin/** = authcBasic </value> </property> </bean>
这个时候就遇到一个问题,Shiro过滤器都是干什么用的?
anon | org.apache.shiro.web.filter.authc.AnonymousFilter |
authc | org.apache.shiro.web.filter.authc.FormAuthenticationFilter |
authcBasic |
org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
|
perms |
org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
|
port |
org.apache.shiro.web.filter.authz.PortFilter
|
rest |
org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
|
roles |
org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
|
ssl | org.apache.shiro.web.filter.authz.SslFilter |
user | org.apache.shiro.web.filter.authc.UserFilter |
写道
rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString
是你访问的url里的?后面的参数。
perms:例子/admins/user/**=perms[user:add:*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于
isPermitedAll()方法。
roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要认证才能使用,没有参数
authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
这些过滤器分为两组,一组是认证过滤器,一组是授权过滤器。其中anon,authcBasic,auchc,user是第一组,
perms,roles,ssl,rest,port是第二组
port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString
是你访问的url里的?后面的参数。
perms:例子/admins/user/**=perms[user:add:*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于
isPermitedAll()方法。
roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要认证才能使用,没有参数
authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
这些过滤器分为两组,一组是认证过滤器,一组是授权过滤器。其中anon,authcBasic,auchc,user是第一组,
perms,roles,ssl,rest,port是第二组
authcBasic就是弹出一个登录窗口,要求用户输入用户名和密码。适合于对安全性要求不高的系统或设备中,如大家所用路由器的配置页面的认证
还有就是自定义过滤器了,举个官方的例子
<bean id="myCustomFilter" class="com.class.that.implements.javax.servlet.Filter"/> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="filterChainDefinitions"> <value> /some/path/** = authc, myCustomFilter </value> </property> </bean>
在Spring的配置文件中添加securityManager和realm,加了个ehcache
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="shiroDbRealm" /> <property name="cacheManager" ref="shiroEhcacheManager" /> </bean> <bean id="shiroDbRealm" class="com.**.ShiroDbRealm"> <property name="accountService" ref="accountService"/> </bean> <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:security/ehcache-shiro.xml"/> </bean>
ehcache的配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xml> <ehcache updateCheck="false" name="shiroCache"> <!-- http://ehcache.org/ehcache.xml --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" /> </ehcache>
又加上了AOP的权限控制和生命周期的配置
<!-- 保证实现了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="true" /> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean>
以上已经将配置的东西都弄完了,好像很简单的样子
配置完成就是Java的一些实现了,先说Realm
public class ShiroDbRealm extends AuthorizingRealm { protected AccountService accountService; /** * 认证回调函数,登录时调用. */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; User user = accountService.findUserByLoginId(token.getUsername()); if (user != null) { if ("disabled".equals(user.getStatus())) { throw new DisabledAccountException(); } byte[] salt = Encodes.decodeHex(user.getSalt()); return new SimpleAuthenticationInfo(new ShiroUser(user.getLoginId(), user.getName()), user.getPassword(), ByteSource.Util.bytes(salt), getName()); } else { return null; } } /** * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用. */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal(); User user = accountService.findUserByLoginId(shiroUser.loginName); if (user != null) { Hibernates.initLazyProperty(user.getRoles()); } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); for (Role role : user.getRoles()) { // 基于Role的权限信息 info.addRole(role.getName()); // 基于Permission的权限信息 info.addStringPermissions(role.getPermissionList()); } return info; } /** * 设定Password校验的Hash算法与迭代次数. */ @PostConstruct public void initCredentialsMatcher() { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(AccountService.HASH_ALGORITHM); matcher.setHashIterations(AccountService.HASH_INTERATIONS); setCredentialsMatcher(matcher); } public void setAccountService(AccountService accountService) { this.accountService = accountService; } }
自定义了一个ShiroUser,目的是为了保存更多的用户信息
/** * 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息. */ public static class ShiroUser implements Serializable { private static final long serialVersionUID = -1373760761780840081L; public String loginName; public String name; public ShiroUser(String loginName, String name) { this.loginName = loginName; this.name = name; } public String getName() { return name; } /** * 本函数输出将作为默认的<shiro:principal/>输出. */ @Override public String toString() { return loginName; } /** * 重载hashCode,只计算loginName; */ @Override public int hashCode() { return Objects.hashCode(loginName); } /** * 重载equals,只计算loginName; */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ShiroUser other = (ShiroUser) obj; if (loginName == null) { if (other.loginName != null) { return false; } } else if (!loginName.equals(other.loginName)) { return false; } return true; } }
建了两个PO,user,role
public class User implements Serializable { private Long id; private String loginId; private String password; private String salt; private String name; private String email; private Integer status; private List<Role> roles = Lists.newArrayList(); ... get/set... }
public class Role implements Serializable { private Long id; private String name; private String permissions; ...get/set... public List<String> getPermissionList() { return ImmutableList.copyOf(StringUtils.split(permissions, ",")); } }
OK。其他的就是登录页面和Controller了,这个就不说了。
相关推荐
- **Spring配置Shiro**:通过Spring的Bean定义来配置Shiro,如定义 Realm 实现,将认证和授权逻辑注入到Spring的上下文中。 - **AOP集成**:利用Spring的AOP功能,可以在方法执行前/后进行权限检查,实现细粒度的...
在本项目实例中,我们将深入探讨如何将Shiro与Spring框架整合,以实现更高效、灵活的安全控制。 1. **Shiro基础** Apache Shiro 提供了用户认证、权限授权、加密和会话管理四大核心功能。认证是指验证用户身份,...
手把手教你集成spring cloud + shiro微服务...用最少的工作量,改造基于shiro安全框架的微服务项目,实现spring cloud + shiro 框架集成。博客地址:https://blog.csdn.net/weixin_42686388/article/details/103084289
这个实例是专为初学者设计的,旨在帮助他们理解和实现基于CAS的单点登录(Single Sign-On, SSO)系统,同时结合Shiro进行权限管理和认证。下面我们将详细探讨这些技术以及它们如何协同工作。 **CAS (Central ...
2. **过滤器链**:Spring Security基于Servlet Filter实现,通过配置过滤器链,可以实现请求级别的安全控制。 3. **认证与授权**:Spring Security支持多种认证方式,如Basic Auth、Form Login、Remember Me等,...
但是该套实现,代码质量非常差(10几个java文件,都快吓晕),并且redis的连接没有基于spring,而是在java代码中硬编码,这几乎无法容忍。 为此,本人基于spring连接redis,吸取了他们文章的思想,重新写了一套解决...
- **用户认证**:Shiro 提供了多种认证方式,如基于表单的身份验证、记住我功能等。 - **权限控制**:通过角色和权限设置,实现对 URL 或方法的访问控制。 - **会话管理**:Shiro 可以管理和监控用户的会话,支持...
- Shiro可与Spring Session集成,实现分布式会话管理,特别适用于微服务架构。 7. **安全最佳实践**: - 使用强密码策略,包括长度限制、字符组合和定期更换。 - 为敏感操作启用CSRF防护。 - 对敏感数据进行...
在这个项目中,我们看到"springcloud-shiro"是一个基于Spring Boot的Shiro实现,其中还应用了Spring Cloud的相关组件,特别是Zuul作为边缘服务进行API网关路由。 Shiro是一个强大且易用的Java安全框架,提供了认证...
1. **松耦合**:Shiro 可以独立于 Spring 使用,但整合后,可以通过 Spring 的 DI 和 AOP 实现更灵活的配置和控制。 2. **统一管理**:整合后,Shiro 的安全控制可以与其他 Spring 组件一起管理,如事务、缓存等,...
将Shiro与Spring整合,可以充分利用两者的优点,实现更高效、更灵活的安全管理。 在"shiro与spring整合工程源代码"中,我们可以看到以下几个关键的知识点: 1. **Shiro的核心组件**: - **Authentication(认证)...
在"shiro-spring.rar"这个压缩包中,我们很显然看到了一个基于Maven构建的项目,它整合了Apache Shiro与Spring框架,但未包含Spring MVC部分。这意味着这是一个后端安全控制的实现,可能适用于RESTful API或传统的...
通过以上步骤,我们可以构建一个集成了 Spring Boot 和 Shiro 的权限认证管理系统,能够实现用户登录、权限校验、会话管理等功能,同时利用缓存提升系统性能。在实际开发中,还可以根据需求扩展 Shiro 功能,例如...
5. **安全注解**:在 Spring MVC 控制器的方法上使用 Shiro 提供的注解(如 `@RequiresAuthentication`、`@RequiresRoles` 和 `@RequiresPermissions`),实现基于方法的权限控制。 6. **登录和登出处理**:编写...
总结来说,这个基于Shiro、Spring MVC和MyBatis的权限管理系统实现了从用户认证到资源访问控制的全过程,为企业级应用提供了安全的访问控制机制。通过学习和实践这个项目,开发者可以深入理解Java Web安全框架的应用...
Spring Shiro-training项目旨在提供一个综合的学习环境,帮助开发者理解和掌握如何在Spring应用中集成Apache Shiro框架,实现安全、高效的身份验证与授权。 Apache Shiro是一个强大且易用的Java安全框架,它处理了...
Spring Boot是基于Spring框架的快速开发工具,它简化了配置并提供了“开箱即用”的特性。在本项目中,Spring Boot用于搭建后端服务,包括数据库连接、RESTful API设计以及自动配置等。Spring Security可以作为Spring...
总之,这个"spring+springMVC+shiro 完美例子"是一个很好的学习资源,帮助开发者深入理解如何在Java Web应用中集成和使用这些强大的框架,实现安全、高效的权限管理。通过分析和实践这个例子,开发者不仅可以提升...
这是一个基于Spring Boot、Apache Shiro、Spring MVC、MyBatis、Quartz和Druid的数据源管理框架的示例项目,名为"renren-security"。这个DEMO提供了完整的权限管理和任务调度解决方案,下面是这些技术栈的核心知识点...
2. **Spring Session Data Redis**:基于Spring Session项目,利用Redis存储用户会话,实现跨服务器的会话共享。这对于分布式系统中的SSO至关重要,因为用户登录状态需要在所有应用之间同步。 集成步骤如下: 1. **...