jeecmsv8 shiro 分析
来源:互联网 发布:java template模板 编辑:程序博客网 时间:2024/06/05 15:03
源代码注释可见 https://github.com/chenbo19867758/jeecmsV8-BoBo.git
1.后台登录页面
/jeeadmin/jeecms/login.do
web.xml中
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <!-- targetFilterLifecycle 允许代理注入Spring bean 解决因为filter比bean先加载,也就是spring会先加载filter指定的类到container中,这样filter中注入的spring bean就为null了 设置为true由servlet容器控制filter的生命周期 --> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> <!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean 这里未设置 自动找到 shiro-context.xml 中的 shiroFilter bean 过滤 <init-param> <param-name>targetBeanName</param-name> <param-value>shiroFilter</param-value> </init-param> --> </filter>
shiro-context.xml 配置了
/jeeadmin/jeecms/login.do = authc
请求登录时会进入自定义过滤器 authcFilter
<bean id="authcFilter" class="com.jeecms.core.security.CmsAuthenticationFilter" parent="adminUrlBean"> <!-- 登录成功后进入的页面 --> <property name="adminIndex" value="/jeeadmin/jeecms/index.do" /> </bean>
CmsAuthenticationFilter 中
public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { boolean isAllowed = isAccessAllowed(request, response, mappedValue); // 判断是否登录页面的请求,转向登录页面 if (isAllowed && isLoginRequest(request, response)) { try { issueSuccessRedirect(request, response); } catch (Exception e) { logger.error("", e); } return false; } return isAllowed || onAccessDenied(request, response, mappedValue); }
/** * 在这返回成功页面successUrl */ protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; String successUrl = req.getParameter(RETURN_URL); if (StringUtils.isBlank(successUrl)) { if (req.getRequestURI().startsWith( req.getContextPath() + getAdminPrefix())) { // 后台直接返回首页,这里为 /jeeadmin/jeecms/index.do successUrl = getAdminIndex(); // 清除SavedRequest WebUtils.getAndClearSavedRequest(request); WebUtils.issueRedirect(request, response, successUrl, null,true); return; } else { // 返回默认的成功页,AuthenticationFilter 中 DEFAULT_SUCCESS_URL = "/"; successUrl = getSuccessUrl(); } } WebUtils.getAndClearSavedRequest(request); WebUtils.issueRedirect(request, response, successUrl, null,true); //WebUtils.redirectToSavedRequest(req, res, successUrl); }
判断是否登录页面的请求, 登录页面转向的成功页面,并区分前端登录和后端登录
登录失败则跳转到spring mvc 映射的路径, CmsLoginAct 中
// 登录失败转向这里 // submit 名称不是固定的随便取, 只需匹配 @RequestMapping @RequestMapping(value = "/login.do", method = RequestMethod.POST) public String submit(String username, HttpServletRequest request, HttpServletResponse response, ModelMap model) { Object error = request.getAttribute(DEFAULT_ERROR_KEY_ATTRIBUTE_NAME); if (error != null) { model.addAttribute("error", error); Integer errorRemaining= unifiedUserMng.errorRemaining(username); model.addAttribute("errorRemaining", errorRemaining); } //此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径 //登陆失败还到login页面 return "login"; }
shiro详解
<?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:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd" default-lazy-init="true"> <!-- web.xml中 对应名称 <filter-name>shiroFilter</filter-name> --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- Shiro的核心安全接口,这个属性是必须的 --> <property name="securityManager" ref="securityManager" /> <!-- /login.jspx 前端用户登录地址 --> <property name="loginUrl" value="/login.jspx" /> <!-- successUrl认证成功统一跳转地址,不配置,shiro认证成功自动到上一个请求路径 --> <property name="successUrl" value="/" /> <!-- 这是因为shiro源代码中判断了filter是否为AuthorizationFilter, 只有perms,roles,ssl,rest,port才是属于AuthorizationFilter(授权), 而anon,authcBasic,auchc,user是AuthenticationFilter(验证),所以unauthorizedUrl(未被授权的url)设置后不起作用。 这里不需要配置 unauthorizedUrl --> <!-- 自定义filter配置 --> <property name="filters"> <util:map> <!-- 下面配置 authcFilter bean --> <entry key="authc" value-ref="authcFilter" /> <!-- 下面配置 userFilter bean --> <entry key="user" value-ref="userFilter" /> <!-- 退出过滤器, 下面配置 logoutFilter bean --> <entry key="logout" value-ref="logoutFilter" /> </util:map> </property> <!-- anon匿名 authc登录认证 user用户已登录 logout退出filter anon:例子/admins/**=anon 没有参数,表示可以匿名使用。 authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数 roles(角色):例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。 perms(权限):例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。 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里的?后面的参数。 authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证 ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查 user是介于,anon和authc直之间的。换句话来说:而“/authenticated= user”表示访问该地址的用户是身份验证通过或RememberMe 登录的都可以。或者说,某个页面需要登录才能看,但这个页面信息又不太重要,就可已使用这个 --> <!-- 后台首页登录 /jeeadmin/jeecms/login.do 后台登录页面访问的接口 /jeeadmin/jeecms/login.do = authc 配置为需要验证权限登录 需要过来器<entry key="authc" value-ref="authcFilter" /> 过滤 --> <!-- filterChainDefinitions Shiro连接约束配置,即过滤链的定义 Shiro Filter的执行顺序 “ 自上而下,从左到右” --> <property name="filterChainDefinitions"> <value> *.jspx = anon *.jhtml = anon /member/forgot_password.jspx = anon /member/password_reset.jspx = anon /member/jobapply.jspx = anon /login.jspx = authc /logout.jspx = logout /member/** = user /jeeadmin/jeecms/login.do = authc /jeeadmin/jeecms/logout.do = logout /jeeadmin/jeecms/** =user </value> </property> </bean> <!-- Shiro Filter --> <!-- 全局定义adminLogin,adminPrefix 供下面的bean使用 --> <bean id="adminUrlBean" class="com.jeecms.core.security.CmsAdminUrl"> <property name="adminLogin" value="/jeeadmin/jeecms/login.do" /> <property name="adminPrefix" value="/jeeadmin/jeecms/" /> </bean> <!-- 自定义过滤 parent="adminUrlBean" 继承adminUrlBean 注入的属性 --> <bean id="authcFilter" class="com.jeecms.core.security.CmsAuthenticationFilter" parent="adminUrlBean"> <!-- 登录成功后进入的页面 --> <property name="adminIndex" value="/jeeadmin/jeecms/index.do" /> </bean> <!-- <entry key="user" value-ref="userFilter" /> 配置过滤 user 权限的访问地址 /member/** = user /jeeadmin/jeecms/** =user --> <bean id="userFilter" class="com.jeecms.core.security.CmsUserFilter" parent="adminUrlBean" /> <!-- 退出过滤器 --> <bean id="logoutFilter" class="com.jeecms.core.security.CmsLogoutFilter" parent="adminUrlBean" /> <!-- 核心管理类 入口, security 安全,--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="cacheManager" ref="shiroEhcacheManager" /> <property name="rememberMeManager" ref="rememberMeManager" /> <property name="realm" ref="authorizingRealm" /> <!-- 凭证匹配器 --> </bean> <!-- 凭证匹配器,核心验证登录与权限授权 --> <bean id="authorizingRealm" class="com.jeecms.core.security.CmsAuthorizingRealm"> <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <!-- 加密的方式,MD5 --> <property name="hashAlgorithmName" value="MD5" /> <!-- true means hex encoded, false means base64 encoded --> <property name="storedCredentialsHexEncoded" value="true" /> <!-- 迭代次数,散列的次数 ,加密的次数,2的话就是加密后把加密的值再加密一次 --> <property name="hashIterations" value="1" /> </bean> </property> <property name="cmsUserMng" ref="cmsUserMng" /> </bean> <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <!-- <property name="cacheManagerConfigFile"> <value>classpath:ehcache-shiro.xml</value> </property> --> <property name="cacheManager"> <ref local="cacheManager" /> </property> </bean> <!-- 会话Cookie模板 --> <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <!-- constructor-arg 构造器注入 前端登录或后端登录,可以传入rememberMe 参数实现记住我功能 rememberMe是cookie的名字 --> <constructor-arg value="rememberMe" /> <property name="httpOnly" value="true" /> <property name="maxAge" value="31536000" /><!-- 365天 --> </bean> <!-- rememberMe管理器 cipherKey是加密rememberMe Cookie的密钥;默认AES算法; --> <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" /> <property name="cookie" ref="rememberMeCookie" /> </bean> <!-- Enable Shiro Annotations for Spring-configured beans. Only run after --> <!-- the lifecycleBeanProcessor has run: jeecms-servlet-admin.xml中配置使用 lifecycleBeanPostProcessor Shiro生命周期处理器 LifecycleBeanPostProcessor用于在实现了Initializable接口的Shiro bean初始化时调用Initializable接口回调, 在实现了Destroyable接口的Shiro bean销毁时调用 Destroyable接口回调。 如UserRealm就实现了Initializable, 而DefaultSecurityManager实现了Destroyable。 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /></beans>
阅读全文
0 0
- jeecmsv8 shiro 分析
- JEECMSv8系统标签详解
- shiro内置过滤器分析
- Spring+Shiro案例分析
- Spring+Shiro案例分析
- Shiro源码分析
- shiro登录过程分析
- Shiro-Subject 分析
- shiro登录过程分析
- shiro功能架构分析
- JEECMSv8安装部署图文教程
- Shiro源码分析-初始化-Realm
- Shiro简单授权原理分析
- shiro认证授权源码分析
- Shiro源码分析-初始化-SecurityManager
- shiro注解授权源码分析
- Shiro源码分析----认证流程
- Shiro源码分析----登录流程
- Oracle数据库之——分组查询,子查询及添加,更新,删除
- 计蒜客-扫雷游戏
- 第四周 单链表应用
- JDBC往mysql里存入中文的问题
- <mvc:annotation-driven /> 作用
- jeecmsv8 shiro 分析
- fragment的切换与隐藏(无需重建)
- HDU 3549:Flow Problem
- mapreduce计算平均值
- 今日头条频道管理
- PHP链接数据库
- abs() -- PHP取绝对值函数
- 软工视频总结(一)
- JAVA 将文件压缩为zip文件