简体   繁体   English

Spring Security JSP授权标签不起作用

[英]Spring security jsp authorize tag not working

I have following spring security configurations: 我具有以下春季安全性配置:

<security:http auto-config="true">  
    <security:intercept-url pattern="/**" access="permitAll" />
    <security:form-login 
        login-processing-url="/j_spring_security_check"
        login-page="/login" 
        default-target-url="/" 
        authentication-failure-url="/login?error"
        username-parameter="login"
        password-parameter="password" />  
    <security:logout logout-url="/j_spring_security_logout" logout-success-url="/login" />
    <security:csrf disabled="true"/>
</security:http>

I want to make specific page(let's say index page("/")) accessible for everybody(both authenticated and non-authenticated users), but, at the same time, be able to manage which parts should be seen in jsp depending on whether user is authenticated or not, and its roles. 我想让所有人(经过身份验证的用户和未经身份验证的用户)都可以访问特定的页面(比如说索引页面(“ /”)),但是同时,可以管理哪些部分应该在jsp中显示,具体取决于用户是否通过身份验证及其角色。

My jsp part looks like this: 我的jsp部分看起来像这样:

<%@ page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:main>
    <jsp:attribute name="title">
        Posts
    </jsp:attribute>
    <jsp:body>
        <sec:authorize access="hasRole('ADMIN')">
            <a href="/blog/createPost">Create post</a>
        </sec:authorize>

        <br>

        <c:forEach var="post" items="${posts}">
            <hr width="300" align="left">
            <div>
                <h4><a href="/blog/viewPost/${post.id}">${post.title}</a></h4>
                <div>${post.content}</div>
            </div>
        </c:forEach>
    </jsp:body>
</t:main>

All authentication mechanism works fine. 所有身份验证机制都可以正常工作。 The problem is that, the link is never displayed, even if I log in using 'ADMIN' role . 问题是,即使我使用“ ADMIN”角色登录,也永远不会显示该链接

I tried debugging my UserDetailsService implementation and verified that 'ADMIN' role is successfully fetched and filled into userdetails: 我尝试调试UserDetailsS​​ervice实现,并验证是否已成功获取“ ADMIN”角色并将其填充到用户详细信息中:

@Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
    User user = userDao.findOneByLogin(login);

    if (user == null) {
        throw new UsernameNotFoundException(login + " not found");
    }

    List<GrantedAuthority> authList = new ArrayList<>();
    List<Role> roles = user.getRoles();

    for (Role role : roles) {
        authList.add(new SimpleGrantedAuthority(role.getName()));
    }

    return new org.springframework.security.core.userdetails.User(
            user.getLogin(), user.getPassword(), authList);
}

Thanks, in advance! 提前致谢!

After a few hours of searching and reading Spring Security 4 docs, finally, I realized the reason of the problem. 经过几个小时的搜索和阅读Spring Security 4文档,终于,我意识到了问题的原因。

Here is some info from spring docs: 这是来自Spring文档的一些信息:

hasRole([role])

Returns true if the current principal has the specified role. 如果当前主体具有指定角色,则返回true。 By default if the supplied role does not start with 'ROLE_' it will be added. 默认情况下,如果提供的角色不是以“ ROLE_”开头,则会添加该角色。 This can be customized by modifying the defaultRolePrefix on DefaultWebSecurityExpressionHandler. 这可以通过修改DefaultWebSecurityExpressionHandler上的defaultRolePrefix进行自定义。

hasAuthority([authority])

Returns true if the current principal has the specified authority. 如果当前主体具有指定的权限,则返回true。

So, according to the statements above, we can conclude that, by default, Spring Security 4 expects all your "roles" to start with "ROLE_" prefix, while all others are threated as simple authorities/permissions. 因此,根据上述陈述,我们可以得出结论,默认情况下,Spring Security 4期望您的所有“角色”都以“ ROLE_”前缀开头,而其他所有角色都将受到简单权限/权限的威胁。

In my case I had "ADMIN" role saved in database, and whenever I tried checking role like hasRole('ADMIN') Spring was converting this to hasRole('ROLE_ADMIN') , thus evaluating this expression to false. 就我而言,我在数据库中保存了“ ADMIN”角色,并且每当尝试检查类似hasRole('ADMIN')角色时,Spring都会将其转换为hasRole('ROLE_ADMIN') ,从而将该表达式评估为false。

There are two types of fixes here, either I rename my 'ADMIN' role to 'ROLE_ADMIN' (as Spring expects it) in database or use hasAuthority('ADMIN') expression instead. 这里有两种类型的修复程序,或者在数据库中将“ ADMIN”角色重命名为“ ROLE_ADMIN”(如Spring期望的那样),或者改用hasAuthority('ADMIN')表达式。

Your problem seems to be in the configuration. 您的问题似乎出在配置中。 In order to use hasRole , hasAnyRole expressions you need to set use-expressions="true" in the security:http tag. 为了使用hasRolehasAnyRole表达式,您需要在security:http标记中设置use-expressions="true"

<security:http auto-config="true" use-expressions="true">  

Else you have to directly use the role name directly in your security tag, 否则,您必须直接在安全标签中直接使用角色名称,

<sec:authorize access="ADMIN">
    <a href="/blog/createPost">Create post</a>
</sec:authorize>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM