shiro

子云 2016-03-23

shiro入门

博客分类:shiro

shiro

一、介绍:

shiro是apache提供的强大而灵活的开源安全框架,它主要用来处理身份认证,授权,企业会话管理和加密。

shiro功能:用户验证、用户执行访问权限控制、在任何环境下使用sessionAPI,如cs程序。可以使用多数据源如同时使用oracle、mysql。单点登录(sso)支持。rememberme服务。详细介绍还请看官网的使用手册:http://shiro.apache.org/reference.html

与springsecurity区别,个人觉得二者的主要区别是:

1、shiro灵活性强,易学易扩展。同时,不仅可以在web中使用,可以工作在任务环境内中。

2、acegi灵活性较差,比较难懂,同时与spring整合性好。

如果对权限要求比较高的项目,个人建议使用shiro,主要原因是可以很容易按业务需求进行扩展。

附件是对与shiro集成的jar整合及源码。

二、shiro与spring集成

shiro默认的配置,主要是加载ini文件进行初始化工作,具体配置,还请看官网的使用手册(http://shiro.apache.org/web.html)init文件不支持与spring的集成。此处主要是如何与spring及springmvc集成。

1、web.xml中配置shiro过滤器,web.xml中的配置类使用了spring的过滤代理类来完成。

Xml代码收藏代码

<filter>

<filter-name>shiroFilter</filter-name>

<filter-class>

org.springframework.web.filter.DelegatingFilterProxy

</filter-class>

</filter>

<filter-mapping>

<filter-name>shiroFilter</filter-name>

<url-pattern>/*</url-pattern

</filter-mapping>

2、在spring中的application.xml文件中添加shiro配置:

Xml代码收藏代码

<!--securityManager是shiro的核心,初始化时协调各个模块运行-->

<beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

<!--单个realm使用realm,如果有多个realm,使用realms属性代替-->

<propertyname="realm"ref="leopardRealm"/>

<propertyname="cacheManager"ref="shiroEhcacheManager"/>

</bean>

<!--realm配置,realm是shiro的桥梁,它主要是用来判断subject是否可以登录及权限等-->

<beanid="leopardRealm"class="com.leopard.shiro.realm.LeopardRealm"/>

<!--shiro过滤器配置,bean的id值须与web中的filter-name的值相同-->

<beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

<propertyname="securityManager"ref="securityManager"/>

<!--没有权限或者失败后跳转的页面-->

<propertyname="loginUrl"value="/login/login.jsp"/>

<propertyname="successUrl"value="/main/index.jsp"/>

<propertyname="unauthorizedUrl"value="/login/unauthorized"/>

<propertyname="filterChainDefinitions">

<value>

/login/logoutlogout=logout

/login/**=anon

/**=authc,rest

</value>

</property>

</bean>

<!--用户授权/认证信息Cache,采用EhCache缓存-->

<beanid="shiroEhcacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager">

<propertyname="cacheManagerConfigFile"value="classpath:ehcache-shiro.xml"/>

</bean>

配置说明:

securityManager是shiro的核心,初始化时协调各个模块运行。

realm是shiro的桥梁,进行数据源配置,shrio提供了常用的realm数据源配置,如LDAP的JndiLdapRealm,JDBC的JdbcRealm,ini文件的IniRealm,properties文件的PropertiesRealm等,也可以插入自己的Realm实现来代表自定义的数据源。此处使用了自定义的leopardRealm进行配置,java代码如下:

Java代码收藏代码

publicclassLeopardRealmextendsAuthorizingRealm{

/**

*授权方法,在配有缓存的情况下,只加载一次。

*/

protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){

SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo();

//获取用户信息的所有资料,如权限角色等.

//info.setStringPermissions(权限集合);

//info.setRoles(角色集合);

returninfo;

}

/**

*登陆认证

*/

@Override

protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokentoken)

throwsAuthenticationException{

UsernamePasswordTokenusernamePasswordToke=(UsernamePasswordToken)token;

Stringusername=usernamePasswordToke.getUsername();

returnnewSimpleAuthenticationInfo(newShiroUser("admin","admin"),"admin",

ByteSource.Util.bytes("admin"),getName());

}

}

shiroFilter:shiro的权限过滤器配置,可自定义过滤器并关联至filterChainDefinitions中。shiro过滤器说明:

shiro过滤器对应的类:

过滤器名称对应的java类

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

anon:例子/admins/**=anon没有参数,表示可以匿名使用。

authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数。

authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证。

roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。

perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。

rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method],其中method为post,get,delete等。

port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。

ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https

user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查

注:这些过滤器中anon,authcBasic,auchc,user是认证过滤器,perms,roles,ssl,rest,port是授权过滤器

至此配置工作已完成。

简单登录操作:

login.jsp代码

Jsp代码收藏代码

<%@pagelanguage="java"pageEncoding="UTF-8"%>

<html>

<body>

<formaction="${pageContext.request.contextPath}/login"method="post">

用户名:<inputid="username"name="username"/>

密码:<inputid="password"type="password"name="password"/>

记住我:<inputtype="checkbox"name="rememberMe"/>

<inputtype="submit"name="submit"value="submit"/>

</form>

</body>

</html>

springMVC控制层代码:

Java代码收藏代码

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importorg.apache.shiro.SecurityUtils;

importorg.apache.shiro.authc.AuthenticationException;

importorg.apache.shiro.authc.IncorrectCredentialsException;

importorg.apache.shiro.authc.UnknownAccountException;

importorg.apache.shiro.authc.UsernamePasswordToken;

importorg.apache.shiro.subject.Subject;

importorg.springframework.stereotype.Controller;

importorg.springframework.web.bind.annotation.RequestMapping;

importorg.springframework.web.servlet.ModelAndView;

@Controller("loginAction")

@RequestMapping("/login")

publicclassLoginAction{

@RequestMapping("")

//登录

publicModelAndViewexecute(HttpServletRequestrequest,

HttpServletResponseresponse,Stringusername,Stringpassword){

UsernamePasswordTokentoken=newUsernamePasswordToken(username,password);

//记录该令牌

token.setRememberMe(false);

//subject权限对象

Subjectsubject=SecurityUtils.getSubject();

try{

subject.login(token);

}catch(UnknownAccountExceptionex){//用户名没有找到

ex.printStackTrace();

}catch(IncorrectCredentialsExceptionex){//用户名密码不匹配

ex.printStackTrace();

}catch(AuthenticationExceptione){//其他的登录错误

e.printStackTrace();

}

//验证是否成功登录的方法

if(subject.isAuthenticated()){

returnnewModelAndView("/main/index.jsp");

}

returnnewModelAndView("/login/login.jsp");

}

//退出

@RequestMapping("/logout")

publicvoidlogout(){

Subjectsubject=SecurityUtils.getSubject();

subject.logout();

}

}

最后启动服务登录,实验证明,失败返回登录页,成功进入主页。

相关推荐