您的位置:首页 > 其它

项目中用到Shiro安全配置用于系统的登录和权限认证

2013-02-01 00:00 531 查看
自己的项目中很多都用到了Shiro的配置来管理验证登录和权限认证,所以自己简单的小结一下,这里暂时只解释登录验证这一块。

(1)首先在项目的WEB-INF目录下的web.xml配置中:


加上

<!--ShiroSecurityfilter-->
<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>*.htm</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>*.json</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<!--ShiroSecurityfilter-->

上面的配置是对请求地址后缀的过滤和转发

这里我的欢迎页的配置直接配置login.jsp了。还是在web.xml中最后加上

<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>

(2)在项目的上下文配置applicationContext.xml中加上:

<importresource="security/applicationContext-shiro.xml"/>

这样的话,就能引入applicationContext-shiro.xml的配置,在这个配置中


全文配置如下:

<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-2.0.xsd"default-lazy-init="true">

<description>Shiro安全配置</description>

<!--Shiro'smainbusiness-tierobjectforweb-enabledapplications-->
<beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<propertyname="realm"ref="shiroDbRealm"/>
<propertyname="cacheManager"ref="shiroEhcacheManager"/>
</bean>

<!--項目自定义的Realm-->
<beanid="shiroDbRealm"class="com.baishi.website.User.MyDbRealm">
<propertyname="userService"ref="userService"/>
<!--可配置cachetoken<->认证信息的cache,用于REST等需要频繁认证的场景-->
<!--<propertyname="authorizationCachingEnabled"value="true"/>-->
</bean>

<beanid="myAuthc"class="com.baishi.website.base.filter.MyFormAuthenticationFilter"/>

<!--ShiroFilter-->
<beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<propertyname="securityManager"ref="securityManager"/>
<propertyname="loginUrl"value="/login.htm"/>
<propertyname="successUrl"value="/admin.htm"/>
<propertyname="unauthorizedUrl"value="/unauthorized.htm"/>
<propertyname="filters">
<util:map>
<entrykey="myAuthc"value-ref="myAuthc"/>
</util:map>
</property>
<propertyname="filterChainDefinitions">
<value>
/logout.htm=logout
/**=myAuthc
</value>
</property>
</bean>

<!--用户授权信息Cache,采用EhCache-->
<beanid="shiroEhcacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager">
<propertyname="cacheManagerConfigFile"value="classpath:security/ehcache-shiro.xml"/>
</bean>

<!--保证实现了Shiro内部lifecycle函数的bean执行-->
<beanid="lifecycleBeanPostProcessor"class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

<!--AOP式方法级权限检查-->
<beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor">
<propertyname="proxyTargetClass"value="true"/>
</bean>
<beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<propertyname="securityManager"ref="securityManager"/>
</bean>
</beans>

这里面我们关注的是:項目自定义的Realm,在我的目录下com.baishi.website.User.MyDbRealm找到MyDbRealm这个类


MyDbRealm类的代码如下:

packagecom.baishi.website.User;

importcom.baishi.website.entity.Users;
importorg.apache.shiro.authc.*;
importorg.apache.shiro.authz.AuthorizationInfo;
importorg.apache.shiro.authz.SimpleAuthorizationInfo;
importorg.apache.shiro.realm.AuthorizingRealm;
importorg.apache.shiro.subject.PrincipalCollection;

publicclassMyDbRealmextendsAuthorizingRealm{

privateUserServiceuserService;

/**
*认证回调函数,登录时调用.
*/
@Override
protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokentoken)throwsAuthenticationException{
UsernamePasswordTokenupToken=(UsernamePasswordToken)token;
Usersuser=userService.findUserByLoginName(upToken.getUsername());
if(user==null){
thrownewUnknownAccountException("Noaccountfoundforuser["+user.getUsername()+"]");
}

returnnewSimpleAuthenticationInfo(user,user.getPassword(),getName());
}

/**
*授权查询回调函数,进行鉴权但缓存中无用户的授权信息时调用.
*/
@Override
protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){
Usersuser=(Users)principals.fromRealm(getName()).iterator().next();
//user=userService.findAuthDetails(user);
if(user!=null){
SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo();
//			for(Rolerole:user.getRoles()){
//				//基于Role的权限信息
//				info.addRole(role.getName());
//			}
//			info.addStringPermissions(user.getPermissions());
returninfo;
}else{
returnnull;
}
}

publicvoidsetUserService(UserServiceuserService){
this.userService=userService;
}
}

其中你只要关注:认证回调函数,登录时调用这个方法,到时候断点到这里看一下验证。

继续解释applicationContext-shiro.xml的配置:其中MyFormAuthenticationFilter这个类是超时的类配置:

代码如下:

packagecom.baishi.website.base.filter;

importorg.apache.ibatis.logging.LogFactory;
importorg.apache.shiro.web.filter.authc.FormAuthenticationFilter;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.io.IOException;

publicclassMyFormAuthenticationFilterextendsFormAuthenticationFilter{

static{
LogFactory.useStdOutLogging();
}

@Override
protectedvoidsaveRequestAndRedirectToLogin(ServletRequestrequest,ServletResponseresponse)throwsIOException{
HttpServletRequestrequest1=(HttpServletRequest)request;
HttpServletResponseresponse1=(HttpServletResponse)response;
Stringuri=request1.getRequestURI();
if(uri.endsWith(".json")){
response1.setHeader("sessionstatus","timeout");
}else{
saveRequest(request);
redirectToLogin(request,response);
}
}
}

继续解释配置中<propertyname="loginUrl"value="/login.htm"/>

<propertyname="successUrl"value="/admin.htm"/>

两个属性对应的是登录和成功登录后的两个页面,这里我是在webapp根目录的两个页面:



其中login,jsp的页面代码:

<%@pagelanguage="java"contentType="text/html"pageEncoding="UTF-8"%>
<%@taglibprefix="shiro"uri="http://shiro.apache.org/tags"%>

<%
Stringpath=request.getContextPath();
StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<basehref="<%=basePath%>">
<title>博客后台登陆</title>
<shiro:authenticated>
<scripttype="text/javascript">
window.location.href='index.htm';
</script>
</shiro:authenticated>
</head>

<body>
<p>用户登录</p>

<formid="form1"name="form1"method="post"action="login.htm">
<inputtype="hidden"name="method"value="login"/>
<tablewidth="335"height="84"border="0"cellpadding="1"cellspacing="1">
<tr>
<td>用户名:</td>
<td><label>
<inputtype="text"name="username"id="username"/>
</label></td>
</tr>
<tr>
<td>密码:</td>
<td><label>
<inputtype="password"name="password"id="password"/>
</label></td>
</tr>
<tr>
<td><label>
<inputtype="submit"name="button"id="button"value="登录"/>
</label></td>
<td><label></label></td>
</tr>
</table>
</form>
<p> </p>
</body>

</html>

其中引入shiro的标签,并且

<shiro:authenticated>
<scripttype="text/javascript">
window.location.href='index.htm';
</script>
</shiro:authenticated>

重定向到index.htm这个页面。

另外在applicationContext-shiro.xml的配置中引入

<!--用户授权信息Cache,采用EhCache-->
<beanid="shiroEhcacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager">
<propertyname="cacheManagerConfigFile"value="classpath:security/ehcache-shiro.xml"/>
</bean>

ehcache-shiro.xml的配置如下:

<ehcacheupdateCheck="false"name="shiroCache">

<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
</ehcache>

到此applicationContext-shiro.xml的配置就完成了。

现在实际操作的时候,在用户的Controller类中,我们写上简单代码:


packagecom.baishi.website.User;

importcom.alibaba.fastjson.JSON;
importcom.baishi.website.base.support.BaseControllerSupport;
importcom.baishi.website.entity.Users;
importorg.springframework.stereotype.Controller;
importorg.springframework.ui.Model;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RequestMethod;
importjavax.annotation.Resource;
importjavax.servlet.http.HttpServletRequest;
importjava.util.List;
importjava.util.Map;

@Controller
@RequestMapping
publicclassUserControllerextendsBaseControllerSupport{
/**
*用户登录后台
*/
@RequestMapping(value="/login",method=RequestMethod.POST)
publicStringhome(){
return"login";
}

@RequestMapping(value="/login",method=RequestMethod.GET)
publicStringlogin(){
return"login";
}

@RequestMapping(value={"admin","index"})
publicStringadmin(){
return"admin";
}

}

最后还要说的是在MyDbRealm类中findUserByLoginName()这个方法,自己简单的在service层写一个根据用户名查询数据库的方法就行了,在xml中的查询语句:

<selectid="findByLoginName"parameterType="String"resultType="Users">
SELECT
*
FROMusers
WHERE
username=#{username}
LIMIT1
</select>

到此就简单的介绍了,用shiro验证登录的配置。解释一下整个过程的流程吧,启动tomcat,首先进入web.xml中过滤→到Controller类中转到视图页面login.jsp→进入了登录的页面,填入信息提交→到MyDbRealm类中验证回调的方法→验证成功后重定向到主页admin.htm

最后贴两张登录的图:




后续有很多开发填坑的文章发布,如果对你有帮助,请支持和加关注一下

http://e22a.com/h.05ApkG?cv=AAKHZXVo&sm=339944

https://shop119727980.taobao.com/?spm=0.0.0.0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐