Pra*_*ngh 65 java spring spring-mvc spring-security
我正在使用无状态弹簧安全性,但在注册的情况下我想禁用spring security.I禁用使用
antMatchers("/api/v1/signup").permitAll().
Run Code Online (Sandbox Code Playgroud)
但它不起作用,我收到以下错误:
 message=An Authentication object was not found in the SecurityContext, type=org.springframework.security.authentication.AuthenticationCredentialsNotFoundException
Run Code Online (Sandbox Code Playgroud)
我认为这意味着Spring安全过滤器正在运行
我的网址顺序总是"/ api/v1"
我的春天配置是
@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);
    }
Run Code Online (Sandbox Code Playgroud)
我的验证过滤器是
@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;
        }
Run Code Online (Sandbox Code Playgroud)
我的控制器是
@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";
    }
}
Run Code Online (Sandbox Code Playgroud)
我对春天来说是全新的,请帮我怎么做?
M. *_*num 120
使用permitAll它时意味着每个经过身份验证的用户,但是您禁用了匿名访问,因此无法使用.
你想要的是忽略某些URL,以覆盖configure获取WebSecurity对象和ignore模式的方法.
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/api/v1/signup");
}
Run Code Online (Sandbox Code Playgroud)
并从该HttpSecurity部分中删除该行.这将告诉Spring Security忽略此URL并且不对它们应用任何过滤器.
小智 13
我有一个更好的方法:
http
    .authorizeRequests()
    .antMatchers("/api/v1/signup/**").permitAll()
    .anyRequest().authenticated()
Run Code Online (Sandbox Code Playgroud)
        小智 8
<http pattern="/resources/**" security="none"/>
Run Code Online (Sandbox Code Playgroud)
或者使用Java配置:
web.ignoring().antMatchers("/resources/**");
Run Code Online (Sandbox Code Playgroud)
而不是旧的:
 <intercept-url pattern="/resources/**" filters="none"/>
Run Code Online (Sandbox Code Playgroud)
为exp.禁用登录页面的安全性:
  <intercept-url pattern="/login*" filters="none" />
Run Code Online (Sandbox Code Playgroud)
        正如@M.Deinum 已经写了答案。
我尝试使用 api /api/v1/signup。它将绕过过滤器/自定义过滤器,但浏览器会调用一个额外的请求/favicon.ico,因此,我也在 web.ignoring() 中添加了它,它对我有用。
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/api/v1/signup", "/favicon.ico");
}
Run Code Online (Sandbox Code Playgroud)
对于上述问题,也许这不是必需的。
这可能不是您问题的完整答案,但是,如果您正在寻找禁用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());
    }
}
Run Code Online (Sandbox Code Playgroud)
我已经包含了完整的配置,但关键是:
.csrf().ignoringAntMatchers("/contact-email")
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           104856 次  |  
        
|   最近记录:  |