本文共 5281 字,大约阅读时间需要 17 分钟。
一、Shiro简介:(示例ShiroDemo2)
Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
Web Support:Web支持,可以非常容易的集成到Web环境;
Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
Shiro的对外API核心就是Subject;
Subject:主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;即一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者;
SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject;可以看出它是Shiro的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器;
Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。
二、代码实现及配置
shiroFilter org.springframework.web.filter.DelegatingFilterProxy targetFilterLifecycle true shiroFilter /*
/toLogin = anon /regist = anon /index.jsp = anon /login = anon/logout = logout /toAdmin = roles[admin]/toUser = roles[user]/** = authc
//登录@RequestMapping(value="/login",method=RequestMethod.POST)public String login(@RequestParam("username") String username,@RequestParam("password")String password){//1.创建subject类型 的实例Subject currentUser = SecurityUtils.getSubject();//2.判断用户是否登录if(currentUser.isAuthenticated()==false) {//3.未登录,将用户名和密码封装到UsernamePasswordTokenUsernamePasswordToken token = new UsernamePasswordToken(username, password);try {//4.认证--自动调用自定义的realmcurrentUser.login(token);}catch (Exception e) {return "/error";}}return "/success";}
public class ShiroRealm extends AuthorizingRealm{@Autowiredprivate UserDao userDao;/**登录认证方法* 1.deoGetAuthenticationInfo,获取认证信息,如果数据库中没有数据,返回null,如果得到正确的用户名和密码,返回指定类型对象* 2.AuthenticationInfo 可以使用SimpleAuthenticationInfo实现类,封装正确的用户名和密码* 3.token参数,就是我们需要认证的token(是从currentUser.login(token);传过来的token)**/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {SimpleAuthenticationInfo info=null;//1.将token转换成UsernamePasswordTokenUsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;//2.获取用户名即可(前台输入的用户名)String username = usernamePasswordToken.getUsername();//3.查询数据库,是否存在指定的用户名和密码User user = userDao.findByUname(username);if(null !=user) {//4.如果查询到了,封装查询结果,返回给我们的调用Object principal=username;//正确的用户名Object credentials=user.getPassword();//数据库存储密码String realmName=this.getName();//前台输入的密码进行盐值加密ByteSource salt = ByteSource.Util.bytes(user.getId().toString());info = new SimpleAuthenticationInfo(principal, credentials, salt, realmName);}else {//5.如果没有查询到,抛出一个异常throw new AuthenticationException();}return info;}/**权限认证方法* 参数列表:PrincipalCollection 登录的身份 登录的用户名* return 返回值:SimpleAuthorizationInfo 封装获取用户对应的所有角色,SimpleAuthorizationInfo(Setroles)*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {SimpleAuthorizationInfo info=null;try {String username = principal.toString();//3.查询数据库,是否存在指定的用户名和密码User user = userDao.findByUname(username);if (null != user) {Set roles = new HashSet ();roles.add(user.getRoles());info = new SimpleAuthorizationInfo(roles);} else {//5.如果没有查询到,抛出一个异常throw new AuthenticationException();}} catch (Exception e) {}return info;}}
三、applicationContext-shiro.xml具体的解析
/toAdmin = roles[admin]/toUser = roles[user]
四、shiro授权其它
概念:
授权:控制哪一个用户可以访问哪一个web资源
主体:Subject,用户
资源:可以访问的url
权限:
角色:包含多个权限
shiro授权方式:
授权之roles拦截器realm实现:
例如:/admin.jsp = roles[admin]
登录的用户如果拥有admin角色可以访问admin.jsp
realm可以帮助我们进行数据库交互,获取指定认证成功的用户对应的角色。
配置一个授权管理器:
转载地址:http://lebxz.baihongyu.com/