在Spring安全性中使用intercept-url

Luc*_*uke 16 java spring spring-security java-ee

intercept-url在Spring安全性中,在元素中创建模式的首选方法是什么?我正在创建一个Web服务(RESTful),我目前要求所有用户都登录并拥有该角色ROLE_USER.然后,通过@PreAuthorize服务层上的注释强制执行进一步的约束.但是,添加intercept-url具有不同配置的多个元素是否常见?

cab*_*ery 20

我认为"首选方式"必然是"主观的".我有自己的<intercept-url>元素security.xml,但放弃了它们,转而@RequestMapping使用@PreAuthorize控制器上的注释.这纯粹是个人偏好(在我的例子中),因为我赞成用Java而不是XML命名空间来保存东西,尽可能这样做.

您可以使用其中一个,另一个或两者,并且可以使注释增强XML - 例如,您可以使用以下内容:

security.xml:

<intercept-url pattern="/something" access="hasRole('ROLE_USER')"/>
Run Code Online (Sandbox Code Playgroud)

YourController.java:

@RequestMapping(value="/something/else")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String getSomethingElseContents(){ return "somethingelse"; }
Run Code Online (Sandbox Code Playgroud)

正如我所说,这似乎只是一个偏好问题.使用XML命名空间的好处是基本访问规则都在一个地方,易于阅读,易于遵循.@PreAuthorize(或其他注释变体)强加的规则特别性感,因为您可以在其中调用自己的SpEL表达式,并根据对所传递的参数或类可访问的字段(@PreAuthorize("@my.project.package.hasMagicPower(#power.INVISIBILITY)")或其组合)的访问权限做出许可决定.您可以应用命名空间选项不可用的逻辑和动态权限.

当然,您可以使用'和','或'和'!'来应用基本逻辑.命名空间中SpEL表达式中的连接符(并且您可以通过@XML中的指示符访问外部类[boolean]方法),但XML中指定的所有内容都必须是静态的.


tl; dr:个人偏好是偏好,但如果您希望或需要动态灵活性进行权限处理,必须使用注释.如果您既不想要也不需要动态灵活性,那么您可以选择(并且声音参数表明命名空间选项相对于SoC更好).我更喜欢让Java处理它以获得灵活性,因为一旦我设置了XML,我就会把它留在地狱而专注于Java.此外,对SoC视图有一些有说服力的反驳,即一个适当的传统化Java应用程序将其控制器放在易于查找的包中,并具有明显的名称控制.


还是tl;博士:嗯.六分之一,另外六分之一.我说po-tay-to.


Old*_*Pro 10

大多数使用Spring Security的Web应用程序只有几个,intercept-url因为它们只有非常基本的安全要求.您需要对登录和登录错误屏幕以及公共站点的某些方面进行未经身份验证的访问,以便可以使用一些URL模式.然后通常有一个管理部分,然后其他一切都是ROLE_USER.

如果您需要更多角色,通常会将它们与顶级URL路径组件相关联.虽然它不是必需的,但它可以更容易确保资源得到适当保护.

<http realm="Contacts Realm" use-expressions="false">
    <intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/admin/*" access="ROLE_ADMIN"/>
    <intercept-url pattern="/secret/*" access="ROLE_SECRET"/>
    <intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN,ROLE_SECRET"/>
    <http-basic/>
</http>
Run Code Online (Sandbox Code Playgroud)

您必须根据您的使用案例决定是否允许人们拥有多个角色.在应用程序中管理起来有点困难,因此大多数具有简单安全性的人都会设置它,以便用户只有一个角色,然后他们允许多个角色访问受保护的内容.当然,另一种方法是每个URL模式一个角色,并为人们提供多种角色.

无论如何,你的问题(或至少我认为你问的问题)的答案是,通常要做的是每个角色的一个顶级路径组件,以相同的安全限制保护所有资源.当然,您也在该路径前缀下对功能进行分组,因此有些人讨厌这种结构,有些人更喜欢在代码中使用注释.我喜欢我的安全性,我可以在一个地方看到它,并且可以通过查看URL轻松告诉安全性期望是什么.

  • 这是错误的:access="ROLE_ADMIN",应该是“hasRole('ROLE_ADMIN')” (2认同)
  • 这是有道理的,但我使用的是 Spring 4,并且“use-expressions”默认为“true”。请参阅http://www.springframework.org/schema/security/spring-security.xsd,它说它默认为true。我确实看到以前的 Spring 3 默认为 false。值得一提的是,答案中可能需要 use-expressions="false" 。我确实尝试过,没有使用 use-expressions="true",但它不起作用,只有表达式起作用。谢谢。 (2认同)

Mic*_*ael 3

SpringSecurity 的配置取决于您为应用程序选择的身份验证:例如,对于表单身份验证,您要配置没有权限的登录 url 和注销成功 url:

<http realm="Contacts Realm">
    <intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/>
    <logout logout-success-url="/index.jsp"/>
</http>
Run Code Online (Sandbox Code Playgroud)

如果使用基本身份验证,您没有登录和注销 URL,并且配置更简单:

<http realm="Contacts Realm">
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <http-basic/>
</http>
Run Code Online (Sandbox Code Playgroud)

如果您选择基本身份验证,请使用第二个示例。