最近项目(struts2+spring+mybatis)中做了一个权限控制,做个简单的介绍:
基本思路是:在struts2中做一个拦截器,对所有action进行拦截,去判断用户是否有执行该action的权限,有则执行action,无责跳转到权限error页面;当然了,如何判断是否有权限,有很多实现方式,这里我们是写了一个listener,在web容器启动时会去读取一个配置了所有action的权限id的property文件,那么在拦截器拦截到action时就可以用这个信息来判断当前用户是否有权限执行该action。session的验证就更简单了,只要一个拦截器就行,不需要listener。
首先是在struts.xml中配置拦截器:
<!-- 全局配置:拦截器和错误跳转 -->
<package name="global" extends="struts-default">
<result-types>
<result-type name="json" class="org.apache.struts2.json.JSONResult" />
</result-types>
<interceptors>
<!-- セッションインターセプター -->
<interceptor name="sessionCheckInterceptor"
class="jp.com.interceptor.SessionCheckInterceptor" />
<!-- ユーザ権限インターセプター -->
<interceptor name="authCheckInterceptor"
class="jp.com.interceptor.AuthCheckInterceptor" />
<!-- 基本的なスタック -->
<interceptor-stack name="basicStack">
<interceptor-ref name="sessionCheckInterceptor" />
<interceptor-ref name="authCheckInterceptor" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="basicStack" />
<global-results>
<!-- リダイレクト -->
<result name="login" type="redirect">
<param name="location">/web/auth/login.jsp</param>
<param name="loginRedirectUrl">${loginRedirectUrl}</param>
</result>
<!-- リダイレクト -->
<result name="redirect" type="redirectAction">
<param name="actionName">redirect</param>
<param name="namespace">/common</param>
<param name="redirectUrl">${redirectUrl}</param>
</result>
<!-- サーバメンテナンスエラー -->
<result name="maintenance">/web/error/99001.jsp</result>
<!-- システムエラー -->
<result name="systemerror">/web/error/99002.jsp</result>
<!-- セッション切れエラー -->
<result name="sessiontimout">/web/error/99003.jsp</result>
<!-- 二重送信エラー -->
<result name="invalid.token">/web/error/99004.jsp</result>
<!-- アカウントに権限が付与されない場合、ダイアログを表示される。 -->
<result name="noPermit">/web/error/99005.jsp</result>
</global-results>
</package>
再来看下拦截器的实现类:
public class AuthCheckInterceptor extends MethodFilterInterceptor {
/** log */
private static Log log = LogFactory.getLog( AuthCheckInterceptor.class );
@SuppressWarnings("unchecked")
@Override
protected String doIntercept( ActionInvocation invocation ) throws Exception {
log.info( "AuthCheckInterceptor start" );
String interceptResult = null;
HttpSession httpSession = ServletActionContext.getRequest().getSession();
// 获取action动作机能id
String namespace = invocation.getProxy().getNamespace();
String actionname = invocation.getProxy().getActionName();
List<Integer> permisionLst = (List<Integer>) httpSession.getAttribute( "permision" );
String propKey = "";
if ( namespace != null ) {
// 去除namespace中的'/'
for ( int i = 0; i < namespace.length() && namespace.contains( "/" ); i++ ) {
if ( namespace.charAt( i ) == '/' ) {
namespace = namespace.substring( 0, i ) + namespace.substring( i + 1, namespace.length() );
}
}
propKey = namespace.toLowerCase() + ".";
}
propKey += actionname.toLowerCase();
Integer kinouId = KinouIdConsts.kinouID.get( propKey );
// 机能id存在,且机能id为-1(或用户权限包含该机能id),则进入机能
if ( ( kinouId != null && kinouId == -1 ) || ( permisionLst != null && permisionLst.contains( kinouId ) ) ) {
interceptResult = invocation.invoke();
}
// 无权限,则跳转无权限页面
else {
interceptResult = "noPermit";
}
log.info( "AuthCheckInterceptor end" );
return interceptResult;
}
}
这样一来,所有action在执行前都会执行该拦截器,而在拦截器的实现类中判断当前用户是否有权限时,用到了这样一个hashmap:
Integer kinouId = KinouIdConsts.kinouID.get( propKey );
它是从哪里来的呢?这里就用到了Listener。
首先在web.xml中配置监听器:
<listener>
<listener-class>jp.com.listener.PropertyLoaderListener</listener-class>
</listener>
之后当然是该监听器的实现类了:
public class PropertyLoaderListener implements ServletContextListener {
@Override
public void contextDestroyed( ServletContextEvent arg0 ) {
// TODO Auto-generated method stub
}
@Override
public void contextInitialized( ServletContextEvent arg0 ) {
// プロパティファイルを読み込む
String path = "WEB-INF/conf/common.properties";
String filePath = arg0.getServletContext().getRealPath( path );
FileInputStream inputFile;
try {
Properties prop = new Properties();
inputFile = new FileInputStream( filePath );
InputStreamReader reader = new InputStreamReader( inputFile );
prop.load( reader );
// 遍历 Properties
Iterator it = prop.entrySet().iterator();
while ( it.hasNext() ) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
Integer value = Integer.parseInt( (String) entry.getValue() );
KinouIdConsts.kinouID.put( key.toLowerCase(), value );
}
}
catch ( Exception e ) {
e.printStackTrace();
}
}
}
注意到这里是读取common.properties,这个文件很简单:
#权限机能配置
#格式:namespace.action=值
# [-1]:不進行權限驗證 [其他值]:進行權限驗證
# (未配入的值一律当"无权限"处理)
mainmenu.mainmenu=-1
opemgr.opemgrmenu=9
...
这样就搞定了,最后补充一下session拦截器的实现类:
public class SessionCheckInterceptor extends MethodFilterInterceptor {
/** log */
private static Log log = LogFactory.getLog(SessionCheckInterceptor.class);
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
log.info("doIntercept start");
//如果是登录使用的action,用户退出的action,直接强制不进行session过期的验证
if(LoginAction.class == invocation.getAction().getClass()
|| LogoutAction.class == invocation.getAction().getClass())
{
return invocation.invoke();
}
//其他的所有的action都要使用判断session是否过期的拦截器站
// Get operator id from session
OperatorVO opeObj = (OperatorVO) invocation.getInvocationContext()
.getSession().get("ope_obj");
if (null == opeObj) {
return "sessiontimout";
}
log.info("doIntercept end");
return invocation.invoke();
}
}
分享到:
相关推荐
Session是服务器端的一种存储机制,用于跟踪用户状态,尤其在用户登录后,通过Session可以判断用户是否已登录,从而实现权限控制。 首先,我们要理解如何使用Session在页面间传递值。当用户在登录页面输入用户名和...
通过以上步骤,我们就可以在Spring Boot应用中成功地整合Shiro,实现从数据库加载权限、权限动态更新和Session共享。这不仅提高了系统的灵活性和可维护性,还为复杂的企业级应用提供了坚实的安全基础。在实践中,还...
本文将详细探讨如何通过`Filter`实现权限控制,以及与RBAC(Role-Based Access Control,基于角色的访问控制)的关系。首先,让我们理解`Filter`的概念。 `Filter`是Java Servlet API中的一个重要组件,它允许我们...
总结,SpringBoot与Shiro的整合,提供了从数据库加载权限、权限动态更新和Session共享的能力,实现了安全控制与业务逻辑的解耦,提高了开发效率和系统的安全性。在具体实践中,开发者需根据项目需求进行定制化配置,...
以下是使用Shiro实现URL拦截和权限控制的基本步骤: 1. **配置Shiro**:在Spring或者其他的配置文件中,你需要声明并配置Shiro的相关过滤器,如`authc`(用于身份验证)、`perms`(基于权限的拦截)和`roles`(基于...
本资源"struts2_session_权限检查并控制重复登录源码"提供了一个具体的实现方案,下面我们将深入探讨相关的知识点。 1. **Struts2框架**:Struts2是Apache软件基金会下的一个开源项目,它基于MVC设计模式,提供了...
另外,这种方法没有利用ASP.NET内置的身份验证和角色管理框架,如Forms Authentication和Role Provider,这些框架提供了更强大、更灵活的解决方案,可以适应更复杂的权限控制需求。 总结来说,ASP.NET中的权限控制...
在C# WinForm应用开发中,权限控制是一个关键的安全组件,它确保了只有授权的用户才能访问特定的功能或数据。本教程将详细讲解如何在C#...在实际项目中,应根据具体需求设计和实现权限控制,确保系统的安全性和稳定性。
用户登录是指用户通过提供有效的身份凭证(如用户名和密码、手机号码和验证码等)来验证自己的身份,并获得对特定系统、应用程序或网站的访问权限。用户登录是保护用户隐私和数据安全的重要措施,同时也为用户提供...
授权则可以根据角色和权限进行,Shiro提供了一系列API来控制用户对资源的访问。 5. **注意事项**: - 安全性:虽然Redis不是设计为安全存储敏感信息的数据库,但在存储session时,确保对敏感数据进行加密,防止...
Struts2:利用 Filter 和 Session 实现访问控制和身份认证 Struts2 是一个基于 Java 语言的 Web 应用程序框架,它提供了许多功能强大且灵活的组件来帮助开发者快速构建 Web 应用程序。在 Web 应用程序中,身份认证...
它可以通过配置或编程方式轻松集成到SpringBoot应用中,实现对用户角色和权限的控制。 1. **身份验证**:Shiro提供了RememberMe、验证码、多因素认证等多种认证方式,确保用户的身份合法性。 2. **授权**:Shiro...
- 如果验证成功,服务器会创建一个新的Session,并将用户信息(如用户名、用户权限等)存入Session中,通常以键值对的形式,如`session["username"] = "example"`。 - 服务器返回一个包含Session ID的Cookie给...
在权限控制中,过滤器通常用于在请求被路由到目标资源之前进行预处理,比如实现身份验证和授权。例如,一个登录过滤器可以检查每个请求的会话,如果没有找到有效的用户会话,就重定向到登录页面。过滤器链的概念使得...
在Java开发中,Apache Shiro是一个非常流行的安全框架,用于实现身份验证、授权(权限控制)、会话管理和加密等功能。本教程将深入探讨这两种不同的权限控制实现方式:一种不使用Shiro,另一种则是结合Shiro进行权限...
SSM框架,增加权限菜单验证,登录验证;数据库为Mysql.....SSM框架,增加权限菜单验证,登录验证;数据库为Mysql.....SSM框架,增加权限菜单验证,登录验证;数据库为Mysql.....
本文将深入探讨如何利用过滤器实现多层权限控制,并结合给定的标签“源码”和“工具”,来提供一个具体的实践示例。 首先,我们需要理解过滤器在Java Web开发中的作用。在Servlet规范中,过滤器是一个实现了javax....
登录拦截功能通常涉及两个主要部分:登录验证和权限控制。登录验证通常在Controller层实现,通过校验用户名和密码来创建新的Session并保存用户信息。权限控制则是在过滤器或拦截器中实现,检查每个请求是否包含有效...
这段代码启动Session,然后删除`username`和`userflag`两个Session变量,实现用户登出功能。 总结起来,这个实例展示了如何结合使用PHP Session和Cookie进行会员登录验证。Session用于在服务器端存储用户信息,确保...
在描述中提到的"tp5权限控制Auth",Auth是ThinkPHP5内建的一个认证和授权组件,用于处理用户身份验证和权限判断。通过Auth,开发者可以方便地实现如用户登录、权限分配、角色管理等功能。这个压缩包可能包含了完整的...