Mak*_*han 1 java spring jsp spring-mvc spring-security
我有以下弹簧安全配置:
<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>
Run Code Online (Sandbox Code Playgroud)
我想让每个人(经过身份验证的和未经身份验证的用户)都可以访问特定页面(假设索引页面(“/”)),但同时,能够管理哪些部分应该在 jsp 中看到取决于用户是否通过身份验证,及其角色。
我的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>
Run Code Online (Sandbox Code Playgroud)
所有身份验证机制都可以正常工作。问题是,链接永远不会显示,即使我使用 'ADMIN' 角色登录。
我尝试调试我的 UserDetailsService 实现并验证“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);
}
Run Code Online (Sandbox Code Playgroud)
提前致谢!
经过几个小时的搜索和阅读 Spring Security 4 文档,我终于意识到了问题的原因。
以下是 spring 文档中的一些信息:
hasRole([role])如果当前主体具有指定的角色,则返回 true。默认情况下,如果提供的角色不以“ROLE_”开头,则会添加它。这可以通过修改 DefaultWebSecurityExpressionHandler 上的 defaultRolePrefix 来自定义。
hasAuthority([authority])如果当前主体具有指定的权限,则返回 true。
因此,根据上面的陈述,我们可以得出结论,默认情况下,Spring Security 4 期望您的所有“角色”都以“ROLE_”前缀开头,而所有其他角色都以简单的权限/权限受到威胁。
就我而言,我在数据库中保存了“ADMIN”角色,每当我尝试检查角色时,hasRole('ADMIN')Spring 都会将其转换为hasRole('ROLE_ADMIN'),从而将此表达式评估为 false。
这里有两种类型的修复,要么我在数据库中将我的“ADMIN”角色重命名为“ROLE_ADMIN”(正如 Spring 所期望的那样),或者hasAuthority('ADMIN')改为使用表达式。
| 归档时间: |
|
| 查看次数: |
4162 次 |
| 最近记录: |