Spring Security 已将 AccessDecisionManager 和 AccessDecisionVoter 这两个类替换为 AuthorizationManager。很不错。不幸的是,Spring Security 团队再次像往常一样,没有想到为新手提供有用的示例。他们为什么要这么做。似乎只要说现在的做法有所不同就足够了。具体如何,需要新手花无数个小时才能找到答案。无论如何,乌合之众有足够的时间。专业人士肯定知道它是如何工作的......
我想实现一个 AuthorizationManager,它使用自定义投票器扩展当前的 Spring Security 决策逻辑。如果抛出 AccessDeniedException 或 AuthorizationException(至少在遗留示例中,这些异常用于确定是否启动身份验证过程或调用 AccessDeniedHandler),则该投票者应在 ConfigAttributes 的帮助下决定作为最后一个实例。
更准确地说:
我想使用以下权限注释方法:如果用户未登录,则调用这些方法/端点将启动登录过程。其他任何情况都会自动导致 404。
对于遗留类,可以在互联网上找到足够的示例。但对于新的来说什么都没有——什么都没有:(。任何人都可以告诉我在哪里可以找到实现自定义 AuthorizationManager 的示例,该自定义 AuthorizationManager 会考虑现有选民并实现我自己的选民?
提前谢谢了
从 Spring Security 6.0 开始,需要显式保存 SecurityContextRepository: https ://docs.spring.io/spring-security/reference/migration/servlet/session-management.html#_require_explicit_ saving_of_securitycontextrepository
这意味着,如果使用自定义 UsernamePasswordAuthenticationFilter,则必须提供 SecurityContextRepository 才能持久保存 SecurityContext,如下所示:
@Component
public class InternalUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@PostConstruct
private void setup() {
super.setSecurityContextRepository(
new DelegatingSecurityContextRepository(
new RequestAttributeSecurityContextRepository(),
new HttpSessionSecurityContextRepository()));
}
//...
}
Run Code Online (Sandbox Code Playgroud)
尽管此处示例中的 @Max 也在 SecurityFilterChain 中设置了存储库,但在 AuthenticationFilter 中仅指定一次 SecurityContextRepository 似乎就足够了。
我已经测试了这两种变体,并且是否在 FilterChain 中指定了 SecurityContextRepository 似乎并不重要。如果我们为 AuthenticationFilter 和 FilterChain 使用一个 bean,或者为每个 bean 创建新的存储库,似乎也并不重要,如下所示:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true)
public class WebSecurityConfig {
@Bean
public SecurityFilterChain mvcFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(authorize -> authorize …
Run Code Online (Sandbox Code Playgroud) 有谁知道为什么 Hibernate 会抛出这个错误?
org.hibernate.query.SemanticException: Could not interpret path expression 'com.example.entity.security.AccountStatus.Description.ACTIVE'
at org.hibernate.query.hql.internal.BasicDotIdentifierConsumer$BaseLocalSequencePart.resolvePathPart(BasicDotIdentifierConsumer.java:256) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.BasicDotIdentifierConsumer.consumeIdentifier(BasicDotIdentifierConsumer.java:91) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitSimplePath(SemanticQueryBuilder.java:4808) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitIndexedPathAccessFragment(SemanticQueryBuilder.java:4755) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitGeneralPathFragment(SemanticQueryBuilder.java:4724) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitGeneralPathExpression(SemanticQueryBuilder.java:1423) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.grammars.hql.HqlParser$GeneralPathExpressionContext.accept(HqlParser.java:6963) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
Run Code Online (Sandbox Code Playgroud)
据报道,具有错误查询的存储库如下所示:
org.hibernate.query.SemanticException: Could not interpret path expression 'com.example.entity.security.AccountStatus.Description.ACTIVE'
at org.hibernate.query.hql.internal.BasicDotIdentifierConsumer$BaseLocalSequencePart.resolvePathPart(BasicDotIdentifierConsumer.java:256) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.BasicDotIdentifierConsumer.consumeIdentifier(BasicDotIdentifierConsumer.java:91) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitSimplePath(SemanticQueryBuilder.java:4808) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitIndexedPathAccessFragment(SemanticQueryBuilder.java:4755) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitGeneralPathFragment(SemanticQueryBuilder.java:4724) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitGeneralPathExpression(SemanticQueryBuilder.java:1423) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.grammars.hql.HqlParser$GeneralPathExpressionContext.accept(HqlParser.java:6963) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
Run Code Online (Sandbox Code Playgroud)
Description
实体内部的enumAccountStatus
看起来像这样:
@Repository
public interface UserAccountRepository extends JpaRepository<UserAccount, Long> {
@EntityGraph(type = EntityGraph.EntityGraphType.FETCH, attributePaths = {
"accountStatus"
}) …
Run Code Online (Sandbox Code Playgroud)