我正在为自己开发小型Web应用程序,我希望用户可以获得某些操作的某些权限。我的数据库架构如下所示: 2桌:
user (id, username, password, etc...)
user_permission (id, user_id, permission (as string) )
总而言之,每个权限都可以管理一些数据(添加新员工,添加新产品等)。
我有CustomPermissionEvaluator
课程(实施PermissionEvaluator
)。它的相应bean是在与servlet相关的另一个.xml文件中定义的。
这是我的应用程序安全部分代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/logout" access="permitAll" />
<intercept-url pattern="/accessdenied" access="permitAll" />
<intercept-url pattern="/**" access="hasPermission(#user,'ROLE_USER')" />
<form-login login-page="/login" default-target-url="/list"
authentication-failure-url="/accessdenied" />
<logout logout-success-url="/logout" />
</http>
<beans:bean id="customUserService" class="com.mateuszprzybyla.security.CustomUserService"></beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserService">
</authentication-provider>
</authentication-manager>
我最近2小时努力的路线是
<intercept-url pattern="/**" access="hasPermission(#user,'ROLE_USER')" />
我需要它,以便所有未注册登录页面的用户出现。
在示例用户的数据库中,我在ROLE_USER
表中拥有user_permission
权限的实体。当我在没有注册的情况下进入网站时,登录页面显示,并且没关系。但是,如果我输入正确的凭据并通过授权步骤,则会显示403错误(禁止访问)。此外,在调试期间,没有调用hasPermission
方法,这是我一直试图解决的问题。当我尝试将hasPermission
用于单个视图部分(例如一个表)时,它可以很好地工作。
有没有人知道我的配置有什么问题,最重要的是,为什么没有调用hasPermission
方法?如果您对其他课程有任何疑问,请提出要求;)
答案 0 :(得分:0)
从你给出的例子来看,听起来你正在制造比他们需要的更复杂的东西。为什么不遵循加载用户角色(权限列表)和使用
的标准模式<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
要使用hasPermission
表达式,您需要使用expression-handler
选项覆盖内置SecurityExpressionHandler
。
答案 1 :(得分:0)
public class CustomPermissionEvaluator implements PermissionEvaluator{
@Override
public boolean hasPermission(Authentication authentication,
Object targetDomainObject, Object permission) {
String desiredRoleName = (String) targetDomainObject;
if(authentication.isAuthenticated()) { // You don't need this 'if' block, if you have defined an anonymous ROLE for non-logged-in users in your security configuration.
// Checking to see if the user has the roleName passed.
for(GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
if(StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), desiredRoleName)) {
return true;
}
}
return false;
}
@Override
public boolean hasPermission(Authentication authentication,
Serializable targetId, String targetType, Object permission) {
throw new RuntimeException("Not Implementing this.");
}
}
我没有看到你的CustomPermissionEvaluator
课程,所以很难说出你的情况出了什么问题。这是一个示例PermissionEvaluator
实现。
通常,GrantedAuthority
对象中的Authentication
对象应具有ROLE信息,除非您使用自定义身份验证管理器。您可以调试并查看对象结构,Authentication对象应该在其中的某处包含ROLE信息。
如果您没有看到ROLE信息,您可能需要使用上面user_permission
对象中的'username'在上面的代码中自己查询Authentication
表,如果您使用Hibernate或任何Spring的事务数据库模板,这些注释不会绑定在上面的PermissionEvaluator
类中。您最终可能会在xml配置文件中定义JDBCTemplate,并将其绑定到您的类中以查询user_permission
表。
答案 2 :(得分:0)
我遇到了同样的情况。
<intercept-url pattern="/**" access="hasPermission(#user,'ROLE_USER')" />
请关注spring-docs
就我而言,
<intercept-url access="@webSecurity.checkPermission('chkValue')" pattern="/request"/>
爪哇
public class WebSecurity {
public boolean checkPermission(String permission) {
boolean hasPermission = true;
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
HttpSession session = request.getSession();
@SuppressWarnings("unchecked")
List<String> functionList = (List<String>) session.getAttribute("FUNCTIONS");
if (!functionList.contains(permission.toString())) {
hasPermission = false;
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("WebSecurity URL Permission " + permission + "hasPermission :"+hasPermission);
return hasPermission;
}
}
注意:如果用户已登录,isAuthenticate()将对所有URL进行身份验证。因此,请在此之前使用 access =“@ webSecurity.checkPermission('chkValue')”。
<intercept-url access="isAnonymous()" pattern="/login"/>
<intercept-url access="@webSecurity.checkPermission('S000017')" pattern="/addRequest"/>
<intercept-url access="isAuthenticated()" pattern="/**"/>