使用shiro进行登录校验;自定义realm的实现
2016-06-05 15:49
531 查看
在web中, 用户输入用户名密码登录,我们需要用这些信息和已经注册存在在数据库中的账户信息进行对比,判断用户名和密码是否正确。
shiro提供了自定义realm的实现来进行处理对不同数据源的校验:
realm就是一个安全数据源。可以将其看作为数据库的另一层封装,连接了应用和db
用户提交的数据流到reaml中,reaml中存着数据库中的账户信息,因此进行对比。
1、首先调用Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必
须通过SecurityUtils. setSecurityManager()设置;
2、SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;
3、Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自
定义插入自己的实现;
4、Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认
ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证;
5、Authenticator 会把相应的token 传入Realm,从Realm 获取身份验证信息,如果没有返
回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进
行访问。
自定义realm的实现:在获取securityManager的时候初始化指定了ini配置文件,配置文件中指定让shiro执行自定义的realm,而不是
最初的[users]的这种方式来获取用户名和密码:
自定义realm时候配置文件的写法: realm名称=realm实现类的全路径,shiro反射拿到 ,设置securityManager.realms=$自定义reaml名
多个reaml实现的时候,继续往下追加
类似:
realm1=.......
realm2=.......
realm3=.......
securityManager.realms=$realm1,$realm2,$realm3
shiro的实现:
1.实现Realm接口:
3.在代码中接收用户提交的参数,配置realm:
shiro提供了自定义realm的实现来进行处理对不同数据源的校验:
realm就是一个安全数据源。可以将其看作为数据库的另一层封装,连接了应用和db
用户提交的数据流到reaml中,reaml中存着数据库中的账户信息,因此进行对比。
1、首先调用Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必
须通过SecurityUtils. setSecurityManager()设置;
2、SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;
3、Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自
定义插入自己的实现;
4、Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认
ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证;
5、Authenticator 会把相应的token 传入Realm,从Realm 获取身份验证信息,如果没有返
回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进
行访问。
自定义realm的实现:在获取securityManager的时候初始化指定了ini配置文件,配置文件中指定让shiro执行自定义的realm,而不是
最初的[users]的这种方式来获取用户名和密码:
自定义realm时候配置文件的写法: realm名称=realm实现类的全路径,shiro反射拿到 ,设置securityManager.realms=$自定义reaml名
多个reaml实现的时候,继续往下追加
类似:
realm1=.......
realm2=.......
realm3=.......
securityManager.realms=$realm1,$realm2,$realm3
#声明一个realm myRealm1= com.gjj.test.shiro.RealmService #指定securityManager的realms实现,通过$name来指定realm securityManager.realms=$myRealm1
shiro的实现:
1.实现Realm接口:
package com.gjj.test.shiro; import org.apache.shiro.authc.*; import org.apache.shiro.realm.Realm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 自定义realm的实现 * Created by guojiangjiang on 2016/6/5. */ public class RealmService implements Realm { private static final Logger logger = LoggerFactory.getLogger(RealmService.class); private static final String REAM_NAME = "OwnRealm"; /** * 返回一个唯一的realm名字 * * @return */ @Override public String getName() { return this.REAM_NAME; } /** * 判断此realm是否支持此token * * @param authenticationToken * @return */ @Override public boolean supports(AuthenticationToken authenticationToken) { //是否支持用户名登录的token return authenticationToken instanceof UsernamePasswordToken; } /** * 根据token获取认证信息 * * @param token 认证令牌 * @return * @throws AuthenticationException */ @Override public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String userName = String.valueOf(token.getPrincipal()); String passwd = String.valueOf(token.getCredentials()); int count = 0; if ("jack".equals(userName)) { count += 1; logger.info("用户名正确:{}", userName); } else { throw new UnknownAccountException("用户名错误!"); } if ("12345".equals(passwd)) { count += 1; logger.info("密码正确:{}", passwd); } else { throw new IncorrectCredentialsException("密码错误!!!"); } // 返回认证信息的一个简单实现,三个参数,用户名,密码,域name AuthenticationInfo info = new SimpleAuthenticationInfo(userName, passwd, this.REAM_NAME); return info; } }2.配置 shiro_realm.ini
#声明一个realm myRealm1= com.gjj.test.shiro.RealmService #指定securityManager的realms实现,通过$name来指定realm securityManager.realms=$myRealm1
3.在代码中接收用户提交的参数,配置realm:
package com.gjj.test.shiro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Realm:域,Shiro 从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager * 要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法; * 也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看 * 成DataSource , 即安全数据源。如我们之前的ini 配置方式将使用 * org.apache.shiro.realm.text.IniRealm。 * realm就类似于安全数据源。 * <p/> * Created by guojiangjiang on 2016/6/5. */ public class RealmTest { private static final Logger logger = LoggerFactory.getLogger(RealmTest.class); public static void main(String[] args) { testRealm(); } private static void testRealm() { //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro_ownRealm.ini"); //2、得到SecurityManager实例并绑定给SecurityUtils org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("jack", "12345"); try { //4、登录,即身份验证 subject.login(token); } catch (AuthenticationException e) { //5、身份验证失败 } } }
相关文章推荐
- Homebrew简介和基本使用
- 左式堆
- 深入了解c++的动态绑定和静态绑定
- 【新闻发布系统】VisualStudio2012 C# 注释头模板生成
- 亚洲/重庆时区(陇蜀时区)变迁
- RedHat6.4 上采用RPM包方式安装mysql5.6 整理
- 字符移位
- Java笔试题库之编程题库 总共30道编程题,掌握了就可以应付中级以内Java面试题
- Make项目管理器
- org.hibernate.HibernateException: No Session found for current thread
- 图BFS
- 动态提交表单(对数字的排序)
- 剑指offer(四十)之整数中1出现的次数(从1到n整数中1出现的次数)
- Node学习笔记(三):基于socket.io web版你画我猜(一)
- 【牛腩】总览
- 杭电 1022【火车的出栈入栈】
- SAPUI5:图标icon
- C++第七次实验---最大公约数和最小公倍数
- Java千百问_03基础语法(014)_volatile关键字有什么用
- Django 中related_name,"%(app_label)s_%(class)s_related"