如何禁用特定 url 的 spring 安全性
How to disable spring security for particular url
我正在使用无状态 spring 安全性,但是在注册的情况下我想禁用 spring security.I 使用
禁用
antMatchers("/api/v1/signup").permitAll().
但它不起作用,我收到以下错误消息:
message=An Authentication object was not found in the SecurityContext, type=org.springframework.security.authentication.AuthenticationCredentialsNotFoundException
我认为这意味着 spring 安全过滤器正在工作
我的 url 的顺序总是“/api/v1”
我的 spring 配置是
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
csrf().disable().
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
and().
authorizeRequests().
antMatchers("/api/v1/signup").permitAll().
anyRequest().authenticated().
and().
anonymous().disable();
http.addFilterBefore(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
}
我的身份验证过滤器是
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = asHttp(request);
HttpServletResponse httpResponse = asHttp(response);
String username = httpRequest.getHeader("X-Auth-Username");
String password = httpRequest.getHeader("X-Auth-Password");
String token = httpRequest.getHeader("X-Auth-Token");
String resourcePath = new UrlPathHelper().getPathWithinApplication(httpRequest);
try {
if (postToAuthenticate(httpRequest, resourcePath)) {
processUsernamePasswordAuthentication(httpResponse, username, password);
return;
}
if(token != null){
processTokenAuthentication(token);
}
chain.doFilter(request, response);
} catch (InternalAuthenticationServiceException internalAuthenticationServiceException) {
SecurityContextHolder.clearContext();
logger.error("Internal authentication service exception", internalAuthenticationServiceException);
httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (AuthenticationException authenticationException) {
SecurityContextHolder.clearContext();
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
} finally {
}
}
private HttpServletRequest asHttp(ServletRequest request) {
return (HttpServletRequest) request;
}
private HttpServletResponse asHttp(ServletResponse response) {
return (HttpServletResponse) response;
}
private boolean postToAuthenticate(HttpServletRequest httpRequest, String resourcePath) {
return Constant.AUTHENTICATE_URL.equalsIgnoreCase(resourcePath) && httpRequest.getMethod().equals("POST");
}
private void processUsernamePasswordAuthentication(HttpServletResponse httpResponse,String username, String password) throws IOException {
Authentication resultOfAuthentication = tryToAuthenticateWithUsernameAndPassword(username, password);
SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
httpResponse.setStatus(HttpServletResponse.SC_OK);
httpResponse.addHeader("Content-Type", "application/json");
httpResponse.addHeader("X-Auth-Token", resultOfAuthentication.getDetails().toString());
}
private Authentication tryToAuthenticateWithUsernameAndPassword(String username,String password) {
UsernamePasswordAuthenticationToken requestAuthentication = new UsernamePasswordAuthenticationToken(username, password);
return tryToAuthenticate(requestAuthentication);
}
private void processTokenAuthentication(String token) {
Authentication resultOfAuthentication = tryToAuthenticateWithToken(token);
SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
}
private Authentication tryToAuthenticateWithToken(String token) {
PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token, null);
return tryToAuthenticate(requestAuthentication);
}
private Authentication tryToAuthenticate(Authentication requestAuthentication) {
Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication);
if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) {
throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials");
}
logger.debug("User successfully authenticated");
return responseAuthentication;
}
我的控制器是
@RestController
public class UserController {
@Autowired
UserService userService;
/**
* to pass user info to service
*/
@RequestMapping(value = "api/v1/signup",method = RequestMethod.POST)
public String saveUser(@RequestBody User user) {
userService.saveUser(user);
return "User registerted successfully";
}
}
我是 spring 的新手,请问我该怎么做?
<http pattern="/resources/**" security="none"/>
或Java配置:
web.ignoring().antMatchers("/resources/**");
代替旧的:
<intercept-url pattern="/resources/**" filters="none"/>
对于 exp 。禁用登录页面的安全性:
<intercept-url pattern="/login*" filters="none" />
当使用 permitAll
时,它意味着每个经过身份验证的用户,但是您禁用了匿名访问,因此无法使用。
你想要的是忽略某些 URLs,因为它会覆盖采用 WebSecurity
对象和 ignore
模式的 configure
方法。
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/v1/signup");
}
并从 HttpSecurity
部分删除该行。这将告诉 Spring 安全忽略此 URL 并且不对其应用任何过滤器。
我有更好的办法:
http
.authorizeRequests()
.antMatchers("/api/v1/signup/**").permitAll()
.anyRequest().authenticated()
这可能不是您问题的完整答案,但是如果您正在寻找禁用 csrf 保护的方法,您可以这样做:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/web/admin/**").hasAnyRole(ADMIN.toString(), GUEST.toString())
.anyRequest().permitAll()
.and()
.formLogin().loginPage("/web/login").permitAll()
.and()
.csrf().ignoringAntMatchers("/contact-email")
.and()
.logout().logoutUrl("/web/logout").logoutSuccessUrl("/web/").permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("admin").roles(ADMIN.toString())
.and()
.withUser("guest").password("guest").roles(GUEST.toString());
}
}
我已经包含了完整配置,但关键行是:
.csrf().ignoringAntMatchers("/contact-email")
因为@M.Deinum已经写了答案。
我试过 api /api/v1/signup
。它会绕过 filter/custom 过滤器,但浏览器会为 /favicon.ico
调用一个额外的请求,因此,我也在 web.ignoring() 中添加了它,它对我有用。
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/v1/signup", "/favicon.ico");
}
也许上述问题不需要这个。
如果您想忽略多个 API 端点,您可以使用以下方法:
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests()
.antMatchers("/api/v1/**").authenticated()
.antMatchers("api/v1/authenticate**").permitAll()
.antMatchers("**").permitAll()
.and().exceptionHandling().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
我遇到了同样的问题,这里是解决方案:(已解释)
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.POST,"/form").hasRole("ADMIN") // Specific api method request based on role.
.antMatchers("/home","/basic").permitAll() // permited urls to guest users(without login).
.anyRequest().authenticated()
.and()
.formLogin() // not specified form page to use default login page of spring security.
.permitAll()
.and()
.logout().deleteCookies("JSESSIONID") // delete memory of browser after logout.
.and()
.rememberMe().key("uniqueAndSecret"); // remember me check box enabled.
http.csrf().disable(); **// ADD THIS CODE TO DISABLE CSRF IN PROJECT.**
}
我正在使用无状态 spring 安全性,但是在注册的情况下我想禁用 spring security.I 使用
禁用antMatchers("/api/v1/signup").permitAll().
但它不起作用,我收到以下错误消息:
message=An Authentication object was not found in the SecurityContext, type=org.springframework.security.authentication.AuthenticationCredentialsNotFoundException
我认为这意味着 spring 安全过滤器正在工作
我的 url 的顺序总是“/api/v1”
我的 spring 配置是
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
csrf().disable().
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
and().
authorizeRequests().
antMatchers("/api/v1/signup").permitAll().
anyRequest().authenticated().
and().
anonymous().disable();
http.addFilterBefore(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
}
我的身份验证过滤器是
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = asHttp(request);
HttpServletResponse httpResponse = asHttp(response);
String username = httpRequest.getHeader("X-Auth-Username");
String password = httpRequest.getHeader("X-Auth-Password");
String token = httpRequest.getHeader("X-Auth-Token");
String resourcePath = new UrlPathHelper().getPathWithinApplication(httpRequest);
try {
if (postToAuthenticate(httpRequest, resourcePath)) {
processUsernamePasswordAuthentication(httpResponse, username, password);
return;
}
if(token != null){
processTokenAuthentication(token);
}
chain.doFilter(request, response);
} catch (InternalAuthenticationServiceException internalAuthenticationServiceException) {
SecurityContextHolder.clearContext();
logger.error("Internal authentication service exception", internalAuthenticationServiceException);
httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (AuthenticationException authenticationException) {
SecurityContextHolder.clearContext();
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
} finally {
}
}
private HttpServletRequest asHttp(ServletRequest request) {
return (HttpServletRequest) request;
}
private HttpServletResponse asHttp(ServletResponse response) {
return (HttpServletResponse) response;
}
private boolean postToAuthenticate(HttpServletRequest httpRequest, String resourcePath) {
return Constant.AUTHENTICATE_URL.equalsIgnoreCase(resourcePath) && httpRequest.getMethod().equals("POST");
}
private void processUsernamePasswordAuthentication(HttpServletResponse httpResponse,String username, String password) throws IOException {
Authentication resultOfAuthentication = tryToAuthenticateWithUsernameAndPassword(username, password);
SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
httpResponse.setStatus(HttpServletResponse.SC_OK);
httpResponse.addHeader("Content-Type", "application/json");
httpResponse.addHeader("X-Auth-Token", resultOfAuthentication.getDetails().toString());
}
private Authentication tryToAuthenticateWithUsernameAndPassword(String username,String password) {
UsernamePasswordAuthenticationToken requestAuthentication = new UsernamePasswordAuthenticationToken(username, password);
return tryToAuthenticate(requestAuthentication);
}
private void processTokenAuthentication(String token) {
Authentication resultOfAuthentication = tryToAuthenticateWithToken(token);
SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
}
private Authentication tryToAuthenticateWithToken(String token) {
PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token, null);
return tryToAuthenticate(requestAuthentication);
}
private Authentication tryToAuthenticate(Authentication requestAuthentication) {
Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication);
if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) {
throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials");
}
logger.debug("User successfully authenticated");
return responseAuthentication;
}
我的控制器是
@RestController
public class UserController {
@Autowired
UserService userService;
/**
* to pass user info to service
*/
@RequestMapping(value = "api/v1/signup",method = RequestMethod.POST)
public String saveUser(@RequestBody User user) {
userService.saveUser(user);
return "User registerted successfully";
}
}
我是 spring 的新手,请问我该怎么做?
<http pattern="/resources/**" security="none"/>
或Java配置:
web.ignoring().antMatchers("/resources/**");
代替旧的:
<intercept-url pattern="/resources/**" filters="none"/>
对于 exp 。禁用登录页面的安全性:
<intercept-url pattern="/login*" filters="none" />
当使用 permitAll
时,它意味着每个经过身份验证的用户,但是您禁用了匿名访问,因此无法使用。
你想要的是忽略某些 URLs,因为它会覆盖采用 WebSecurity
对象和 ignore
模式的 configure
方法。
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/v1/signup");
}
并从 HttpSecurity
部分删除该行。这将告诉 Spring 安全忽略此 URL 并且不对其应用任何过滤器。
我有更好的办法:
http
.authorizeRequests()
.antMatchers("/api/v1/signup/**").permitAll()
.anyRequest().authenticated()
这可能不是您问题的完整答案,但是如果您正在寻找禁用 csrf 保护的方法,您可以这样做:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/web/admin/**").hasAnyRole(ADMIN.toString(), GUEST.toString())
.anyRequest().permitAll()
.and()
.formLogin().loginPage("/web/login").permitAll()
.and()
.csrf().ignoringAntMatchers("/contact-email")
.and()
.logout().logoutUrl("/web/logout").logoutSuccessUrl("/web/").permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("admin").roles(ADMIN.toString())
.and()
.withUser("guest").password("guest").roles(GUEST.toString());
}
}
我已经包含了完整配置,但关键行是:
.csrf().ignoringAntMatchers("/contact-email")
因为@M.Deinum已经写了答案。
我试过 api /api/v1/signup
。它会绕过 filter/custom 过滤器,但浏览器会为 /favicon.ico
调用一个额外的请求,因此,我也在 web.ignoring() 中添加了它,它对我有用。
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/v1/signup", "/favicon.ico");
}
也许上述问题不需要这个。
如果您想忽略多个 API 端点,您可以使用以下方法:
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests()
.antMatchers("/api/v1/**").authenticated()
.antMatchers("api/v1/authenticate**").permitAll()
.antMatchers("**").permitAll()
.and().exceptionHandling().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
我遇到了同样的问题,这里是解决方案:(已解释)
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.POST,"/form").hasRole("ADMIN") // Specific api method request based on role.
.antMatchers("/home","/basic").permitAll() // permited urls to guest users(without login).
.anyRequest().authenticated()
.and()
.formLogin() // not specified form page to use default login page of spring security.
.permitAll()
.and()
.logout().deleteCookies("JSESSIONID") // delete memory of browser after logout.
.and()
.rememberMe().key("uniqueAndSecret"); // remember me check box enabled.
http.csrf().disable(); **// ADD THIS CODE TO DISABLE CSRF IN PROJECT.**
}