Apache Shiro Web Support学习笔记

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:

anonorg.apache.shiro.web.filter.authc.AnonymousFilter
authcorg.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasicorg.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
logoutorg.apache.shiro.web.filter.authc.LogoutFilter
noSessionCreationorg.apache.shiro.web.filter.session.NoSessionCreationFilter
permsorg.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
portorg.apache.shiro.web.filter.authz.PortFilter
restorg.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
rolesorg.apache.shiro.web.filter.authz.RolesAuthorizationFilter
sslorg.apache.shiro.web.filter.authz.SslFilter
userorg.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>




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值