shiro概述
原创
©著作权归作者所有:来自51CTO博客作者啄木鸟伍迪_的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、概述:
Apache Shiro 是 Java 的一个安全(权限)框架,其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。可以完成:认证、授权、加密、会话管理、与Web 集成、缓存 等。
jar包下载:https://repo1.maven.org/maven2/org/apache/shiro/shiro-all/1.9.0/shiro-all-1.9.0.jar
源码下载地址(1.9.0 & 1.3.2):(源码下载具有非常好的参考意义)
基本功能:
- Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
- Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用 户是否能进行什么操作,如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户 对某个资源是否具有某个权限;
- Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有 信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
- Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
- Web Support:Web 支持,可以非常容易的集成到Web 环境;
- Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可 以提高效率;
- Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能
- 把权限自动传播过去;
- Testing:提供测试支持;
- Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
- Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登 录了
运行流程:
Subject 代表了当前“用户”,当 应用程序请求(执行)过来时,需要 通过subject 来交互 subject 可以判断用户是否登入;可以获取session;可以判断是否拥有权限等; 这个用户不一定 是一个具体的人,与当前应用交互的任何东西都是 Subject,如网络爬虫, 机器人等;与 Subject 的所有交互都会委托给 SecurityManager; Subject 其实是一个门面,SecurityManager 才是实际的执行者
securitymanager 是安全管理器,管理所有安全相关的交互,管理所有subject,它相当于 SpringMVC 中 DispatcherServlet 的角色;
Realm:Shiro 从 Realm 获取安全数据(如用户、角色、权限),就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户 进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色/ 权限进行验证用户是否能进行操作;可以把 Realm 看成 DataSource

二、shiro的java se demo:
目录结构如下图,其中 Quickstart.java 为源文件中的例子 shiro-root-1.9.0/samples/quickstart/src/main/java/Quickstart.java;shiro.ini为源文件中的文件(shiro-root-1.9.0/samples/quickstart/src/main/resources/shiro.ini);

Quickstart.java: 展示了如何获取到Subject;如何获取session ;是否登入的判断;执行登入;判断用户权限;是否具备某行为;执行登出;
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.muses.shiro;
20
21 import org.apache.shiro.SecurityUtils;
22 import org.apache.shiro.authc.*;
23 import org.apache.shiro.config.IniSecurityManagerFactory;
24 import org.apache.shiro.mgt.SecurityManager;
25 import org.apache.shiro.session.Session;
26 import org.apache.shiro.subject.Subject;
27 import org.apache.shiro.util.Factory;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31
32 /**
33 * Simple Quickstart application showing how to use Shiro's API.
34 *
35 * @since 0.9 RC2
36 */
37 public class Quickstart {
38
39 private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
40
41
42 public static void main(String[] args) {
43
44 // The easiest way to create a Shiro SecurityManager with configured
45 // realms, users, roles and permissions is to use the simple INI config.
46 // We'll do that by using a factory that can ingest a .ini file and
47 // return a SecurityManager instance:
48
49 // Use the shiro.ini file at the root of the classpath
50 // (file: and url: prefixes load from files and urls respectively):
51 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
52 SecurityManager securityManager = factory.getInstance();
53
54 // for this simple example quickstart, make the SecurityManager
55 // accessible as a JVM singleton. Most applications wouldn't do this
56 // and instead rely on their container configuration or web.xml for
57 // webapps. That is outside the scope of this simple quickstart, so
58 // we'll just do the bare minimum so you can continue to get a feel
59 // for things.
60 SecurityUtils.setSecurityManager(securityManager);
61
62 // Now that a simple Shiro environment is set up, let's see what you can do:
63
64
65 //获取当前的subject,调用SecurityUtils.getSubject();
66 // get the currently executing user:
67 Subject currentUser = SecurityUtils.getSubject();
68
69 //测试使用session
70 //获取session:Subject#getSession()
71 // Do some stuff with a Session (no need for a web or EJB container!!!)
72 Session session = currentUser.getSession();
73 session.setAttribute("someKey", "aValue");
74 String value = (String) session.getAttribute("someKey");
75 if (value.equals("aValue")) {
76 log.info("-----》Retrieved the correct value! [" + value + "]");
77 }
78
79 // let's login the current user so we can check against roles and permissions:
80
81 //测试当前的用户是否被认证,即是否已经登入
82 //调用Subject#isAuthenticated()
83 if (!currentUser.isAuthenticated()) {
84 //用户名和密码封装为UsernamePasswordToken对象
85 UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
86 token.setRememberMe(true);
87 try {
88 //执行登入
89 currentUser.login(token);
90 //若没有指定的账户,则shiro将抛出UnknownAccountException
91 } catch (UnknownAccountException uae) {
92 log.info("There is no user with username of " + token.getPrincipal());
93 //若账户存在,但密码不匹配,则shiro将抛出IncorrectCredentialsException
94 } catch (IncorrectCredentialsException ice) {
95 log.info("Password for account " + token.getPrincipal() + " was incorrect!");
96 //若用户被锁定,抛出LockedAccountException
97 } catch (LockedAccountException lae) {
98 log.info("The account for username " + token.getPrincipal() + " is locked. " +
99 "Please contact your administrator to unlock it.");
100 }
101 //所有上面认证异常的父类
102 // ... catch more exceptions here (maybe custom ones specific to your application?
103 catch (AuthenticationException ae) {
104 //unexpected condition? error?
105 }
106 }
107
108 //say who they are:
109 //print their identifying principal (in this case, a username):
110 log.info("----》User [" + currentUser.getPrincipal() + "] logged in successfully.");
111
112 //test a role:
113 if (currentUser.hasRole("schwartz")) {
114 log.info("May the Schwartz be with you!");
115 } else {
116 log.info("Hello, mere mortal.");
117 }
118 //测试用户是否具备某一个行为,调用Subject的isPermitted()的方法;
119 //test a typed permission (not instance-level)
120 if (currentUser.isPermitted("lightsaber:wield")) {
121 log.info("You may use a lightsaber ring. Use it wisely.");
122 } else {
123 log.info("Sorry, lightsaber rings are for schwartz masters only.");
124 }
125 //测试用户是否具备某一行为
126 //a (very powerful) Instance Level permission:
127 if (currentUser.isPermitted("winnebago:drive:eagle5")) {
128 log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +
129 "Here are the keys - have fun!");
130 } else {
131 log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
132 }
133
134 //执行登出调用Subject的logout()的方法;
135 //all done - log out!
136 currentUser.logout();
137
138 System.exit(0);
139 }
140
View Code
三、shiro整合SSM(spring_springmvc_mybatis)
我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。
我要做一个自由又自律的人,靠势必实现的决心认真地活着。