|
Web项目中集成Shrio(web.xml):
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
...
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
shiro.ini存放位置:
1./WEB-INF/shiro.ini;
2.存放在classpath的根目录中(classpath:shiro.ini)。
配置文档功能介绍:
1.EnvironmentLoaderListener的功能是创建IniWebEnvironment实例初始化Shiro的运行环境,获取shiro.ini信息。如果需要自定义初始化,可以使用WebUtils.getRequiredWebEnvironment(servletContext)来进行环境初始化。
2.ShiroFilter将对初始化后的web应用执行过滤操作。
3.filter-mapping设定过滤规则。
(一般情况下,需要将Shiro的filter-mapping定义在最前面,以保证过滤器可以率先执行全局过滤。)
自定义配置文件加载所需配置(舍弃EnvironmentLoaderListener的初始化。web.xml):
<context-param>
<param-name>shiroEnvironmentClass</param-name>
<param-value>com.foo.bar.shiro.MyWebEnvironment</param-value>
</context-param>
自定义的初始化工具类可以加载xml等不同的配置文件。
一、配置文件的路径设置(使用Resource.Utils定义的资源路径前缀)
1.2及以后版本中可以如此定义:
1./WEB-INF/shiro.ini;
2.存放在classpath的根目录中(classpath:shiro.ini)。
在早期版本中必须如此定义:
1.文件系统式:file:/home/foobar/myapp/shiro.ini;
2.相对路径式:classpath:com/foo/bar/shiro.ini;
3.URL式:url:http://confighost.mycompany.com/myapp/shiro.ini。
二、可以在web.xml中直接写shiro.ini的内容:
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
<init-param><param-name>config</param-name><param-value>
# INI Config Here //将ini文件中的配置全部写在这里
</param-value></init-param>
</filter>
...
一般会将shiro的配置独立写在另外的文件:
1.shiro的配置很多,与web.xml中的配置写在一块显得很乱,且不美观;
2.shiro配置需要和web.xml分割开,需要一定独立性;
3.保证web.xml的易读性;
4.保持shiro配置的可重用性。
Web集成Shiro的早期配置方法(web.xml):
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
</filter>
...
<!-- Make sure any request you want accessible to Shiro is filtered. /* catches all -->
<!-- requests. Usually this filter mapping is defined first (before all others) to -->
<!-- ensure that Shiro works in subsequent filters in the filter chain: -->
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
如果shiro.ini文件既不在classpath根目录,也不在Web-INF下,则需要为其设定路径:
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
<init-param>
<param-name>configPath</param-name>
<param-value>/WEB-INF/anotherFile.ini</param-value>
</init-param>
</filter>
...
shiro.ini中urls块的配置:
...
[urls]
/index.html = anon
/user/create = anon
/user/** = authc
/admin/** = authc, roles[administrator]
/rest/** = authc, rest
/remoting/rpc/** = authc, perms["remote:invoke"]
等号左边是需要过滤的对象,右边是过滤所执行的过滤器的名字,过滤器的名字在 main区域中会有定义。如果过滤器需要特殊定义,可以写成filterName[filterUrlPath-过滤器路径]。
过滤器会按照所写的顺序执行。
案例一:
/account/** = ssl, authc
含义:任何通过/account路径,或者其拓展路径/account/foo,/account/bar/baz的行为都会触发ssl、authc过滤器的过滤启动。
案例二:
/account/** = ssl, authc
/account/signup = anon
第二行配置永远执行不了,因为第一行的过滤器已经将符合第二行规则的用户全部过虑掉了(以为这些用户不符合第一行规则)。所以,设定过滤器的顺序很重要。
如果需要实现自定义filter,需要继承org.apache.shiro.web.filter.PathMatchingFilter类。并且在main区域加以配置:
[main]
...
myFilter = com.company.web.some.FilterImplementation
myFilter.property1 = value1
...
[urls]
...
/some/path/** = myFilter
Shiro自带多个filter:
[main]
...
# Notice how we didn't define the class for the FormAuthenticationFilter ('authc') - it is instantiated and available already:
authc.loginUrl = /login.jsp //我们并没有在main区域定义名字为‘authc’的filter,但是shiro本身已经定义了,所以可以直接引用。
...
[urls]
...
# make sure the end-user is authenticated. If not, redirect to the 'authc.loginUrl' above,
# and after successful authentication, redirect them back to the original account page they
# were trying to view:
/account/** = authc
...
已经存在的默认filter:
anon
org.apache.shiro.web.filter.authc.AnonymousFilter
authc
org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic
org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
logout
org.apache.shiro.web.filter.authc.LogoutFilter
noSessionCreation
org.apache.shiro.web.filter.session.NoSessionCreationFilter
perms
org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port
org.apache.shiro.web.filter.authz.PortFilter
rest
org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles
org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl
org.apache.shiro.web.filter.authz.SslFilter
user
org.apache.shiro.web.filter.authc.UserFilter
在Shiro1.2之前如果需要使filter失效,需要将其从配置文件中删除或注释,现在只需添加其状态为不可用即可。
[main]
...
# configure Shiro's default 'ssl' filter to be disabled while testing:
ssl.enabled = false
[urls]
...
/some/path = ssl, authc
/another/path = ssl, roles[admin]
...
实质上,OncePerRequestFilter通过它的isEnabled(request, response)方法来控制某一个filter的启用或停用,可以根据需要重写。它的子类PathMatchingFilter则可以控制路径匹配的过滤,可以根据需要重写。
ServletContainerSessionManager是SessionManager的子类,它可以实现Shiro的session与servlet的session之间的互通与共享。
优点:session拥有共同的配置属性。
缺点:配置属性具有不可移植性。
如果想要对Shiro的session做特殊的配置,则需要启用Shiro的自己的sessionManager机制来代替servlet的session管理机制接管应用中所有的session(shiro.ini)。
[main]
...
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
# configure properties (like session timeout) here if desired
# Use the configured native session manager:
securityManager.sessionManager = $sessionManager
另外,Shiro的本地sessionManager可以设定cookie
1.sessionIdCookieEnabled (a boolean) 设定cookie的可用
2.sessionIdCookie 初始化cookie实例
创建cookie模板(shiro.ini):
[main]
...
securityManager.sessionManager.sessionIdCookie.domain = foo.com
禁用cookie(shiro.ini):
[main]
...
securityManager.sessionManager.sessionIdCookieEnabled = false
记住我功能实现:
java:
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
token.setRememberMe(true);
SecurityUtils.getSubject().login(token);
...
shiro.ini:
[main]
authc.loginUrl = /login.jsp
[urls]
# your login form page here:
login.jsp = authc
jsp:
<form ...>
Username: <input type="text" name="username"/> <br/>
Password: <input type="password" name="password"/>
...
<input type="checkbox" name="rememberMe" value="true"/>Remember Me?
...
</form>
其中这三个参数名字是shiro限定的,如果要改变,需要在shiro.ini中进行配置:
[main]
...
authc.loginUrl = /whatever.jsp
authc.usernameParam = somethingOtherThanUsername
authc.passwordParam = somethingOtherThanPassword
authc.rememberMeParam = somethingOtherThanRememberMe
...
设置记住我的cookie(shiro.ini):
[main]
...
securityManager.rememberMeManager.cookie.name = foo
securityManager.rememberMeManager.cookie.maxAge = blah
...
当然记住我功能是可以定制的(shiro.ini):
[main]
...
rememberMeManager = com.my.impl.RememberMeManager
securityManager.rememberMeManager = $rememberMeManager
JSP引用Shiro
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
案例一(游客登录):
<shiro:guest>
Hi there! Please <a href="login.jsp">Login</a> or <a href="signup.jsp">Signup</a> today!
</shiro:guest>
案例二(用户登录):
<shiro:user>
Welcome back John! Not John? Click <a href="login.jsp">here<a> to login.
</shiro:user>
案例三(验证用户登录):
<shiro:authenticated>
<a href="updateAccount.jsp">Update your contact information</a>.
</shiro:authenticated>
案例四(未认证用户登录):
<shiro:notAuthenticated>
Please <a href="login.jsp">login</a> in order to update your credit card information.
</shiro:notAuthenticated>
案例五(principal标签输出用户验证信息):
Hello, <shiro:principal/>, how are you today?
等同于
Hello, <%= SecurityUtils.getSubject().getPrincipal().toString() %>, how are you today?
案例六(principal从验证属性中取出类型匹配的属性):
User ID: <principal type="java.lang.Integer"/>
等同于
User ID: <%= SecurityUtils.getSubject().getPrincipals().oneByType(Integer.class).toString() %>
案例七(直接通过属性名来取值):
Hello, <shiro:principal property="firstName"/>, how are you today?
等同于
Hello, <%= SecurityUtils.getSubject().getPrincipal().getFirstName().toString() %>, how are you today?
或者
Hello, <shiro:principal type="com.foo.User" property="firstName"/>, how are you today?
或者
Hello, <%= SecurityUtils.getSubject().getPrincipals().oneByType(com.foo.User.class).getFirstName().toString() %>, how are you today?
案例八(指定特定角色):
<shiro:hasRole name="administrator">
<a href="admin.jsp">Administer the system</a>
</shiro:hasRole>
案例九(去除特定角色):
<shiro:lacksRole name="administrator">
Sorry, you are not allowed to administer the system.
</shiro:lacksRole>
案例十(拥有角色集中的某一个):
<shiro:hasAnyRoles name="developer, project manager, administrator">
You are either a developer, project manager, or administrator.
</shiro:lacksRole>
案例十一(拥有特定权限):
<shiro:hasPermission name="user:create">
<a href="createUser.jsp">Create a new User</a>
</shiro:hasPermission>
案例十二(去除特定权限者):
<shiro:hasPermission name="user:create">
<a href="createUser.jsp">Create a new User</a>
</shiro:hasPermission>

 |
|