2014-12-03 66 views
0

我想爲spring-boot REST項目添加安全性。我使用控制器和數據庫的自定義身份驗證,而不是基本的,而不是OAuth。如何在安全的情況下製作spring-boot REST服務?

是否有任何關於如何將安全性添加到spring-boot REST項目的好教程?

我使用的安全配置:

package com.example.control.api; 

import com.example.control.api.shared.service.DatabaseAuthenticationProvider; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.http.HttpMethod; 
import org.springframework.security.authentication.AuthenticationProvider; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; 
import org.springframework.security.web.context.HttpSessionSecurityContextRepository; 
import org.springframework.security.web.context.SecurityContextRepository; 


@Configuration 
@EnableWebMvcSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .requestMatchers() 
       .antMatchers("/", "/greeting") 
       .antMatchers(HttpMethod.POST, "/api/authentication/authenticate") 
       .and() 
       .authorizeRequests() 
       .anyRequest().authenticated(); 
    } 

    @Bean 
    AuthenticationProvider authenticationProvider() { 
     return new DatabaseAuthenticationProvider(); 
    }; 

    @Bean 
    SecurityContextRepository securityContextRepository(){ 
     return new HttpSessionSecurityContextRepository(); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(authenticationProvider()); 
    } 
} 

我使用這個控制器來進行身份驗證:

package com.example.control.api.authentication; 

import com.example.control.api.shared.dao.IUserDAO; 
import com.example.control.api.shared.domain.Employee; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.http.HttpStatus; 
import org.springframework.http.ResponseEntity; 
import org.springframework.security.authentication.AuthenticationManager; 
import org.springframework.security.authentication.BadCredentialsException; 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.context.SecurityContextHolder; 
import org.springframework.security.web.context.SecurityContextRepository; 
import org.springframework.web.bind.annotation.*; 

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

@RestController 
@RequestMapping("/api/authentication") 
public class AuthenticationController { 

    @Autowired 
    //@Qualifier("authenticationManager") 
    AuthenticationManager authenticationManager; 

    @Autowired 
    SecurityContextRepository repository; 

    @Autowired 
    IUserDAO userDAO; 

    @RequestMapping(value = "/authenticate", method = RequestMethod.POST) 
    @ResponseBody 
    public ResponseEntity login(
      @RequestBody AuthenticationDataModel authData, 
      HttpServletRequest request, HttpServletResponse response) { 
     UsernamePasswordAuthenticationToken token = 
       new UsernamePasswordAuthenticationToken(authData.getUsername(), authData.getPassword()); 
     try { 
      Authentication auth = authenticationManager.authenticate(token); 
      SecurityContextHolder.getContext().setAuthentication(auth); 
      repository.saveContext(SecurityContextHolder.getContext(), request, response); 
      return new ResponseEntity((Employee)auth.getDetails(), HttpStatus.OK); 
     } catch (BadCredentialsException ex) { 
      return new ResponseEntity<Employee>(HttpStatus.UNAUTHORIZED); 
     } 


    } 
} 

而且我得到了一個錯誤,當請求此控制器的方法login

java.lang.IllegalStateException: Cannot invoke saveContext on response [email protected]f4cfa. You must use the HttpRequestResponseHolder.response after invoking loadContext 
    at org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext(HttpSessionSecurityContextRepository.java:111) 
    at com.example.control.api.authentication.AuthenticationController.login(AuthenticationController.java:46) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:186) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 

回答

0

請點擊此鏈接 Spring Security Configuration in Spring Boot

你需要知道的三件事

  1. 從你的XML/JAVA /常規配置中添加安全規則
  2. 在春季啓動項目
  3. 禁用默認春季安全 - 你需要創建或更新一個名爲應用用的.properties下面一行: security.basic.enabled =假 並放置在src文件/主/資源
  4. 在情況下,如果你想使用基本安全,只需添加註釋你的java配置 - @EnableWebSecurity
+0

我用REST控制器進行身份驗證。我的情況下,你的解決方案不起作用。我添加了更多關於實現問題的信息。我希望你能幫助我。 – Lunigorn 2014-12-04 01:44:11

相關問題