shiro + extjs
来源:互联网 发布:阿里云域名独立管理 编辑:程序博客网 时间:2024/04/28 16:25
源码下载 我的GITHUB
shiro 相比与spring security配置上简单很多。
加载shiro config
<context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:shiro-config.xml </param-value> </context-param>
添加shrio过滤器,这里需要注意的是,过滤器的名字shiroFilter必须与配置文件里面的bean名字相同
<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>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager"/><!-- override these for application-specific URLs if you like:--><property name="loginUrl" value="/login.html"/> <property name="successUrl" value="/index.html"/> <property name="unauthorizedUrl" value="/unauthorized.html"/> <property name="filters"> <util:map> <entry key="authc" value-ref="formAuthenticationFilter"/> </util:map> </property> <property name="filterChainDefinitions"> <value> /comp/** = anon /pages/** = anon /resources/** = anon /view/** = anon /** = authc </value> </property></bean>
shiroFilter中引用了 securityManageer。如果参考shiro官网的同学请注意,官网documentation中的manager是org.apache.shiro.mgt.DefaultWebSecurityManager。在1.2.2中,这个类是没有实现WebSecurityManager的,所以会跑出unimplement WebSecurityManager的异常。
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!-- Single realm app. If you have multiple realms, use the 'realms' property instead. 如果有多个realm,需要用reamls参数,为实践。--> <property name="realm" ref="fastRealm"/> </bean>
<bean id="fastRealm" class="com.chinadreamer.contacts.filter.shiro.UserRealm"></bean>重写realm。
重写的doGetAuthorizationInfo与doGetAuthenticationInfo在官网中已经很明确的说明了,这里不再解释。
我说下这里会遇到的一个问题。shiro跟spring的filter并没有优先级之分,而用户验证,一般都会涉及到datasource bean的引用,比方这里的userservice。所以需要注意的是必须在spring bean加载之后,进入shiro,否则是无法加载的。
我的做法是在applicationContext.xml 结尾才引入shiro-config.xml,这样就可以获取到bean了。
引入方式比较常规<import resource="shiro-config.xml"/>
public class UserRealm extends AuthorizingRealm{private final static Logger LOGGER = Logger.getLogger(UserRealm.class);@Autowiredprivate UserService userService;public UserRealm(){super();LOGGER.info(" init user realm ");setAuthenticationTokenClass(UsernamePasswordToken.class);}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {User user = ShiroUtils.getUser(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); return authorizationInfo;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken upToken = (UsernamePasswordToken) token; String username = upToken.getUsername(); String password = new String(upToken.getPassword()); User user; try {user = this.userService.userLogin(username, password);} catch (Exception e) {throw new AuthenticationException(e.getMessage(),e);} SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password.toCharArray(), getName());return info;}}
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
简单的shiro到这就可以了。但是如果配合extjs,就需要控制ajax返回,大家知道extj是根据response会写的success 字段来判断的。
<!--替换默认的form 验证过滤器--> <bean id="formAuthenticationFilter" class="com.chinadreamer.contacts.filter.shiro.FastFormAuthenticationFilter"> </bean>
提供一份源码,根据各自的需求改动,这是其他大大提供的。
package com.chinadreamer.contacts.filter.shiro;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.log4j.Logger;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.subject.Subject;import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;public class FastFormAuthenticationFilter extends FormAuthenticationFilter{private static final Logger LOGGER = Logger.getLogger(FastFormAuthenticationFilter.class);/* * 主要是针对登入成功的处理方法。对于请求头是AJAX的之间返回JSON字符串。 */ @Overrideprotected boolean onLoginSuccess(AuthenticationToken token,Subject subject, ServletRequest request, ServletResponse response)throws Exception {HttpServletRequest httpServletRequest = (HttpServletRequest) request;HttpServletResponse httpServletResponse = (HttpServletResponse) response;if (!"XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))) {// 不是ajax请求issueSuccessRedirect(request, response);} else {httpServletResponse.setCharacterEncoding("UTF-8");PrintWriter out = httpServletResponse.getWriter();out.println("{success:true,message:'登入成功'}");out.flush();out.close();}return false;}/** * 主要是处理登入失败的方法 */ @Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { if (!"XMLHttpRequest".equalsIgnoreCase(((HttpServletRequest) request) .getHeader("X-Requested-With"))) {// 不是ajax请求 setFailureAttribute(request, e); return true; } try { response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); String message = e.getClass().getSimpleName(); if ("IncorrectCredentialsException".equals(message)) { out.println("{success:false,message:'密码错误'}"); } else if ("UnknownAccountException".equals(message)) { out.println("{success:false,message:'账号不存在'}"); } else if ("LockedAccountException".equals(message)) { out.println("{success:false,message:'账号被锁定'}"); } else { out.println("{success:false,message:'未知错误'}"); } out.flush(); out.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } return false; } /** * 所有请求都会经过的方法。 */ @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (isLoginRequest(request, response)) { if (isLoginSubmission(request, response)) { if (LOGGER.isTraceEnabled()) { LOGGER.trace("Login submission detected. Attempting to execute login."); } if ("XMLHttpRequest" .equalsIgnoreCase(((HttpServletRequest) request) .getHeader("X-Requested-With"))) {// 不是ajax请求 // String vcode = request.getParameter("vcode"); // HttpServletRequest httpservletrequest = (HttpServletRequest) request; // String vvcode = (String) httpservletrequest // .getSession() // .getAttribute( // com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY); // if (vvcode == null || "".equals(vvcode) // || !vvcode.equals(vcode)) { // response.setCharacterEncoding("UTF-8"); // PrintWriter out = response.getWriter(); // out.println("{success:false,message:'验证码错误'}"); // out.flush(); // out.close(); // return false; // } } return executeLogin(request, response); } else { if (LOGGER.isTraceEnabled()) { LOGGER.trace("Login page view."); } // allow them to see the login page ;) return true; } } else { if (LOGGER.isTraceEnabled()) { LOGGER.trace("Attempting to access a path which requires authentication. Forwarding to the " + "Authentication url [" + getLoginUrl() + "]"); } if (!"XMLHttpRequest" .equalsIgnoreCase(((HttpServletRequest) request) .getHeader("X-Requested-With"))) {// 不是ajax请求 saveRequestAndRedirectToLogin(request, response); } else { // response.setCharacterEncoding("UTF-8"); // PrintWriter out = response.getWriter(); // out.println("{success:true,message:'login'}"); // out.flush(); // out.close(); return true; } return false; } } }
0 0
- shiro + extjs
- shiro
- shiro
- Shiro
- shiro
- shiro
- shiro
- shiro
- Shiro
- Shiro
- shiro
- shiro
- shiro
- shiro
- shiro
- shiro
- shiro
- Shiro
- 局部对象变量调用分线程方法
- Xcode5 使用gitHub上库的SSH地址建立Repository,以及如何通过Xcode把代码传到GitHub
- 3. 字符串匹配算法:朴素的匹配算法、KMP算法。
- Box2D C++ 教程-跳跃
- 用InternetOpen()的下载文件
- shiro + extjs
- 帅哥还是发过节费
- Spring中@Autowired标签与@Resource标签的区别
- 浅谈NFS服务器构建和mount挂载命令
- php面向对象(OOP)编程完全教程
- java打开文件夹(含判断操作系统工具类和解压缩工具类)
- Android UI设计规则
- 安全的VPN服务要流我们在电视上你的iPhone或Android
- 使用jquery attr 赋值后 "&" 变成了"&"