【问题标题】:Securing url pattern based on user properties Spring security基于用户属性保护 url 模式 Spring security
【发布时间】:2015-11-26 20:24:55
【问题描述】:

我已经根据用户角色为我的项目保护了某些 url 模式,如下面的 spring_security xml 所示。

 <security:http auto-config="true" use-expressions="true" access-denied-page="/auth/denied.do" >

    <security:intercept-url pattern="/auth/login" access="permitAll"/>
    <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
    <security:intercept-url pattern="/security/**" access="hasRole('ROLE_SECURITY')"/>
    <security:intercept-url pattern="/common/**" access="hasRole('ROLE_USER')"/>
    <security:intercept-url pattern="/notsecure/**" access="permitAll"/>

    <security:form-login
        login-page="/auth/login.do"
        authentication-failure-url="/auth/login.do?error=true"
        default-target-url="/common/tasks/tasks.do"
        authentication-success-handler-ref="mySuccessHandler"/>

    <security:logout
        invalidate-session="true"
        logout-success-url="/auth/login.do"
        logout-url="/auth/logout.do"/>

</security:http>
<sec:global-method-security pre-post-annotations="enabled" />

<!-- Declare an authentication-manager to use a custom userDetailsService -->
<security:authentication-manager>
    <security:authentication-provider user-service-ref="authenticationService">
        <!--   <security:password-encoder ref="passwordEncoder"/> -->
    </security:authentication-provider> 
</security:authentication-manager>

<!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database -->
<!--
<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
-->

<!-- A custom service where Spring will retrieve users and their corresponding access levels  -->
<bean id="authenticationService" class="ie.premiumpower.services.AuthenticationService"/>
<bean id="mySuccessHandler" class="ie.premiumpower.services.MySuccessHandler">
</bean>

所以只有管理员用户可以访问 /admin/** 等。

现在我想根据不同的属性(他们的 site_id 只是一个 int)将用户限制为他们自己的 url 模式。所以只有site_id为1的用户才能访问url“/1/**”等等。

我该怎么做呢?只是在正确的方向上寻找一个点。到目前为止,我所看到的一切都不允许我拥有可变的 url 模式。如“/{variable}/”。

【问题讨论】:

  • 您可以使用 spring-security 标签库在 JSP 中检查登录用户具有哪些角色。基于此,您可以决定是否显示 URL……如果他们没有看到 URL,他们就不会去那里。如果他们尝试通过一些劫持/黑客攻击,那么它将无法作为 Spring-security 工作,否则您的配置将阻止他们。这是你要找的吗?
  • 不,我已经能够根据角色限制 URL。这是完美的工作。我现在想根据用户的不同属性进行限制。
  • 如果我将浏览器中的 URL 更改为:givemeadminstuff/2/*.. 那你会怎么做?
  • 所有管理页面都使用“/admin/**”访问。没有“管理员”角色的任何人都无法访问这些内容。这完美地工作。没有角色“admin”的人无法访问任何带有“/admin/”的页面。我现在想做一些不同的事情。我想这样做,如果用户想要访问 url“/limitaccess/1/”,他们的 site_id 必须为 1。如果他们想访问“/limitaccess/2/”,他们的 site_id 必须为 2 . 所以每次尝试 url "/limitaccess/x/*" 我想检查 x == 登录用户的 site_id。

标签: spring spring-security


【解决方案1】:

https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html

参见“15.3 方法安全表达式”

你可以使用类似的东西

@PreAuthorize("#value == '123'")
@RequestMapping(value="/secure")
@ResponseBody
public String aloa(@RequestParam("value") String value, Principal principal) {
        return "Hello " + principal.getName();
}

只有在您提供“value=123”作为请求参数时才会让您进入。

您也可以在这里使用@PathVariable:

@PreAuthorize("#value == '123'")
@RequestMapping(value="/secure/{value}/data")
@ResponseBody
public String aloa(@PathVariable("value") String value, Principal principal)

如果您想要对域对象进行细粒度的访问控制,您可能需要使用 spring-acl 来实现此目的。在那里,您可以根据用户权限为任何对象定义细粒度的访问控制。这也是 acl 所基于的简单基础。您可以加入您自己的 PermissionEvaluator 实现,然后在 @PreAuthorize 中使用“hasPermission”:

将其链接到您的安全配置中:

<global-method-security secured-annotations="disabled" pre-post-annotations="enabled">
        <expression-handler ref="expressionHandler"/>
    </global-method-security>

    <beans:bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
        <beans:property name="permissionEvaluator" ref="myPermissionEvaluator"/>
    </beans:bean>

创建一个“hasPermission”PreAuthorize 约束:

@PreAuthorize("hasPermission(#value, 'admin')")
@RequestMapping(value="/secure/{value}/data")
@ResponseBody
public String aloa(@PathVariable("value") String value, Principal principal) 

用生命填充 PermissionEvaluator。在这里,您可以将域权限桥接到 spring-security:@RequestMapping 中的引用值将通过“permission”中的“targetDomainObject”进入,您将找到上面“hasPermission”定义中定义的所需权限。

@Component("myPermissionEvaluator")
public class MyPermissionEvaluator implements PermissionEvaluator {

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
                return ...;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
            Object permission) {
        return ...;
    }

}

您甚至可以直接从注解中访问 Principal 对象:

@PreAuthorize("#value == authentication.principal.title") //我的委托人来自 ldap 源,并且标题是从那里映射的。

【讨论】:

    猜你喜欢
    • 2014-03-07
    • 2014-11-28
    • 2020-04-11
    • 2016-06-03
    • 2016-05-19
    • 2012-03-02
    • 2022-11-17
    • 2016-02-11
    • 2016-02-10
    相关资源
    最近更新 更多