shiro-登录验证
来源:互联网 发布:mysql 2002错误 编辑:程序博客网 时间:2024/06/07 05:48
shiro实现登录验证,可以用它自身的方法来实现,也可以自定义方法来实现登录验证,了解了shiro的登录逻辑,实现自定义的验证逻辑就很简单
1、用shiro方法实现
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 = "/" /> <property name="unauthorizedUrl" value = "/unauthorize"/><property name="filterChainDefinitions"> <value> /static/**=anon /login=authc /logout=logout /unauthorize=authc /**=user,perms </value> </property></bean>由于shiro默认注册了FormAuthenticationFilter,所以配置中可以不需要为此方法定义bean,但有个前提,登录页面中的登录账号和密码,记住我的name必须和FormAuthenticationFilter默认的名称一致,如下图
如果登录页面的name和FormAuthenticationFilter不一致,则需要自己为FormAuthenticationFilter进行配置
<bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"> <property name="usernameParam" value="name"/> <property name="passwordParam" value="password1"/> <property name="rememberMeParam" value="rememberMe1"/> <property name="loginUrl" value="/login"/> <property name="successUrl" value="/"/></bean><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" > <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value = "/login" /> <property name="successUrl" value = "/" /> <property name="unauthorizedUrl" value = "/unauthorize"/><property name="filters"> <map> <entry key="authc" value-ref="formAuthenticationFilter"/> </map> </property><property name="filterChainDefinitions"> <value> /static/**=anon /login=authc /logout=logout /unauthorize=authc /**=user,perms < </value> </property></bean>登录页面提交后,跳转到 /login,进入登录方法,由于此路径权限设置为authc,shiro对该路径进行过滤,authc权限由FormAuthenticationFilter进行过滤。登录请求进入onAccessDenied方法
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (isLoginRequest(request, response)) { //判断是否是登录请求 if (isLoginSubmission(request, response)) { // 是否是http post请求 if (log.isTraceEnabled()) { log.trace("Login submission detected. Attempting to execute login."); } return executeLogin(request, response); } else { if (log.isTraceEnabled()) { log.trace("Login page view."); } //allow them to see the login page ;) return true; } } else { if (log.isTraceEnabled()) { log.trace("Attempting to access a path which requires authentication. Forwarding to the " + "Authentication url [" + getLoginUrl() + "]"); } saveRequestAndRedirectToLogin(request, response); return false; }}其中 executeLogin(request, response)方法的具体实现在继承的AuthenticatingFilter里
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { AuthenticationToken token = createToken(request, response); if (token == null) { String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +"must be created in order to execute a login attempt."; throw new IllegalStateException(msg); } try { Subject subject = getSubject(request, response); subject.login(token); return onLoginSuccess(token, subject, request, response); } catch (AuthenticationException e) { return onLoginFailure(token, e, request, response); }}
剖析:createToken(request, response); 具体实现在子类FormAuthenticationFilter中
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) { String username = getUsername(request); String password = getPassword(request); return createToken(username, password, request, response);}
从上可以看出,具体的登录账号和密码从request中取出来,并创建了token对象,调用subject的login方法,login方法实现大致流程是用token去realm中取AuthenticationInfo对象,AuthenticationInfo对象存放的是正确的登录账号和密码,并和token中数据进行匹配,然后根据匹配情况返回相应的结果。realm中方法需自己实现,大致流程:从token中取出用户登录填写的账号,去查找正确的登录信息,若是查找不到,返回null,如果查找到对应的登录账号和密码,则封装到AuthenticationInfo对象中,并返回该对象。
java代码:
@RequestMapping(value = "/login")public String toLogin(HttpServletRequest request, Model model){ String exceptionClassName = (String)request.getAttribute("shiroLoginFailure"); String error = null; if(UnknownAccountException.class.getName().equals(exceptionClassName)) { error = "用户名/密码错误"; } else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) { error = "用户名/密码错误"; } else if(exceptionClassName != null) { error = "其他错误:" + exceptionClassName; } model.addAttribute("error", error); return "login"; // 跳转到登录页面}
2、自定义登录实现
最关键的是在shiro配置中,登录提交的url需设置为不过滤处理,如提交到/login,则/login=anon,
方法中可实现自己的登录验证逻辑。若是账号密码匹配工作仍要shiro来完成,则将用户填写的账号和密码封装到token对象中,调用subject的login方法。
代码示例:
UsernamePasswordToken token = new UsernamePasswordToken(userName, password); try { subject.login(token); } catch (UnknownAccountException ua){ returnInfo.setMessage("用户名错误"); } catch (IncorrectCredentialsException ic){ returnInfo.setMessage("密码错误"); } }
附:
1)shiro默认注册的filters
public enum DefaultFilter {anon(AnonymousFilter.class),
authc(FormAuthenticationFilter.class),
authcBasic(BasicHttpAuthenticationFilter.class),
logout(LogoutFilter.class),
noSessionCreation(NoSessionCreationFilter.class),
perms(PermissionsAuthorizationFilter.class),
port(PortFilter.class),
rest(HttpMethodPermissionFilter.class),
roles(RolesAuthorizationFilter.class),
ssl(SslFilter.class),
user(UserFilter.class);
}
2)登录异常
UnknownAccountException(账号不存在)IncorrectCredentialsException(密码错误)
DisabledAccountException(帐号被禁用)
LockedAccountException(帐号被锁定)
ExcessiveAttemptsException(登录失败次数过多)
ExpiredCredentialsException(凭证过期)等
0 0
- shiro-登录验证
- shiro登录验证
- shiro 登录验证授权问题
- shiro之登录验证过程
- Shiro登录验证源码解析
- S2SM集成Shiro-登录验证
- Shiro 结合 kcaptcha实现登录验证
- Shiro登录机制验证,自定义FormAuthenticationFilter
- spring mvc整合shiro登录 权限验证
- Apache shiro 登录验证授权管理
- Shiro 登录验证 那点事儿
- spring mvc整合shiro登录 权限验证
- spring mvc整合shiro登录 权限验证
- 使用shiro进行登录密码安全验证
- spring mvc整合shiro登录 权限验证
- Shiro登录验证实例详解与源码
- SpringBoot使用Shiro验证登录笔记
- idea+maven+ssm+shiro开发shiro权限登录,验证码
- Java线程如何按照你想要的顺序执行
- 批处理练习
- POJ 3204 网络流的必须边
- 安装mysql遇到的问题
- HashMap的实现原理
- shiro-登录验证
- form提交时,传递额外的参数
- HTML——建立连接
- linux下查看主板内存槽与内存信息(dmidecode)
- IOS单例模式(Singleton)
- go实用小技能-int类型转成byte类型原理解密
- MVC框架自己封装开启超神之路(上) 3-5视图层的调用
- Python 100练习题[1-10]
- Android键盘面板冲突 布局闪动处理方案