我在添加 /admin
时想到了这个问题端点到 antMatchers("/admin").hasAuthority("ADMIN")
它根本不会产生 获取 请求到 /admin
并返回 200
它返回 403
反而
注:我使用 JWT 作为额外的身份验证层。
这是我的安全配置
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/", "/health", "/authority", "/dashboard", "/users/login", "/logoutUser", "/manageEvents", "/manageAeds", "/manageReports",
"/charts", "/error", "/profile", "/authenticate/**", "/login", "/403", "/userProfile", "/deleteAed", "/users/add").permitAll()
.antMatchers("/admin").hasAuthority("ADMIN")
.antMatchers("/css/**", "/img/**", "/js/**", "/images/**", "/error_css/**", "/scss/**", "/vendor/**").permitAll()
.anyRequest().authenticated().and().
exceptionHandling().accessDeniedPage("/403").and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
By moving it to
permit.All()
it will work but it's not the case here.
这是我处理内部重定向的地方
@Controller
@GetMapping("/authority")
public String getAuth(HttpServletResponse response) {
if (jwt == null) {
return "redirect:/login";
}
if (jwtTokenUtil.isTokenExpired(jwt)) {
return "redirect:/login?token=expired";
}
response.addHeader("Auth", "Bearer " + jwt);
System.out.println(loggedinUser.getRoles());
if (loggedinUser != null) {
if (loggedinUser.getRoles().equalsIgnoreCase("TILEFONITIS")) {
return "redirect:/dashboard"; //will redirect
} else if (loggedinUser.getRoles().equalsIgnoreCase("ADMIN")) {
System.out.println("Admin");
return "redirect:/admin"; //won't redirect
} else if (loggedinUser.getRoles().equalsIgnoreCase("GUEST")) {
return "redirect:/403"; // will redirect
} else {
return "redirect:/dashboard"; // will redirect
}
} else {
return "redirect:/login";
}
}
这是我的 /admin
内@Controller
从来没有被调用过。@GetMapping("/admin")
public String getAdmin(HttpServletResponse response) {
if (jwt == null) {
return "redirect:/login";
}
if (jwtTokenUtil.isTokenExpired(jwt)) {
return "redirect:/login?token=expired";
}
response.addHeader("Auth", "Bearer " + jwt);
System.out.println("jwt" + jwt);
return "admin";
}
The odd thing is that with Postman i get redirected!
我在这里错过了什么?
编辑:第一个电话是在
/authenticate/web
我在哪里告诉 Spring 我已通过身份验证authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(auth.getUsername(), auth.getPassword()));
编辑2:
为了让事情更清楚:
来自 来访网站 , 流动:
/authenticate/web
.js
重定向至 /authority
(获取) /admin
(GET) -> 403 来自 来访 postman , 流动:
/authenticate/web
JWT
并将其包含在标题中并对 /authority
进行 GET 这真的很奇怪,我添加了
jwt
每次都用response.addHeader
在 网站流动 。更新:
加上
JWT
.虽然现在我注意到我得到 302 来自网络而不是 200
正如你所看到的
admin
页面是 403 更新 2:
我设法打破了一些事情,
首先
httpSecurity.addFilterBefore
关于我的安全配置意味着 spring 将寻找
JWT
并在指定过滤器类的位置前添加过滤器那里
hasAuthority()
至 hasRole()
如果您收到 当前用户 您可以自动访问它的权限,如下所示
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
System.out.println("Principal: "+auth.getPrincipal());
System.out.println("Authorities: "+auth.getAuthorities());
Because the
authentication
is overriden by thejwt filter
this means i will only manage to get a user only if the request header contains the validjwt
这就是它从
postman
开始工作的原因但不是来自 web
.另一个问题是,在我的 Controller 中,我试图添加
jwt
在 response
只有当 Controller 完成它的工作时才会添加到它的标题中,我无法在下一行中获得用户主体,因为没有 jwt
到它的请求 header 。此屏幕截图代表网络调用和来自 postman 的调用,两者均访问
/authority
端点。ADMIN
作为权威ROLE_ANONYMOUS
所以我有两个选择来解决这个问题:
REST
端点为 JWT
并为 web 部件使用默认的 spring 安全(hasRole()
等)。 最佳答案
经过大量的反复试验,我设法分解了一些东西,并使用 JWT
使安全工作正常。以及默认 Spring 身份验证 .
为了让它工作,我必须完全改变我的 SecurityConfig
,并将其更改为 MultipleSecurity
.
这是多重安全的工作原理:
与 @Order(1)
注释安全配置被标记为首先要查找的内容。
@Order(1)
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.antMatcher("/api/**").authorizeRequests()
.antMatchers("/api/authenticate/android").permitAll()
.anyRequest().authenticated().and()
.exceptionHandling().accessDeniedPage("/403").and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
@Order(1)
智威汤逊@Order(2)
默认 Spring 安全@Order(2)
@Configuration
public class SecurityConfiguration2 extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.antMatchers("/web/**").hasAuthority("ADMIN")
.and().formLogin().defaultSuccessUrl("/redirect")
.and().logout()
.permitAll();
}
}
我们基本上说这些配置是:JWT
在 /api/**
/web/**
寻找权威所以所有的
/web
端点如 /web/admin
现在需要 authorities
而不是 JWT
!以及来自
/api/**
的所有敏感信息将需要一个 JWT
关于java - Spring Boot 返回 403 虽然我有管理员权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62426705/