1

目前我正在Springboot安全性方面工作,對我來說是相當新的。我跟着YouTube視頻教程Video如何在springboot中調用註冊rest API時獲取oAuth2訪問令牌?

我得到的oauth2的access_token成功,當我用波紋管的代碼片段: -

@SpringBootApplication 
public class MathifyApplication { 
    @Autowired 
    private PasswordEncoder passwordEncoder; 


    public static void main(String[] args) { 
     SpringApplication.run(MathifyApplication.class, args); 
    } 

    @Autowired 
    public void authenticationManager(AuthenticationManagerBuilder builder, UserRepository repository, UserService service) throws Exception { 
     //Setup a default user if db is empty 
     User students = new User("stu1", "user", "user", "[email protected]", "1234567890", "12th", "dwarka sec-12", 
      0, 0 , "may/29/2017", "", Arrays.asList(new Role("USER"), new Role("ACTUATOR"))); 
     if (repository.count()==0){ 
      service.save(students); 
     } 
     builder.userDetailsService(userDetailsService(repository)).passwordEncoder(passwordEncoder); 
    } 

    private UserDetailsService userDetailsService(final UserRepository repository) { 
     return userName -> new CustomUserDetails(repository.findByUsername(userName)); 
    } 

} 

和控制器類是: -

@RestController 
public class LoginController { 
    @Autowired 
    private UserService userService; 

    @RequestMapping(value = "/mathify/getuser/{userId}", method = RequestMethod.GET) 
    public User getUser(@PathVariable String userId){ 
     System.out.println("Userid "+userId); 
     return userService.getUser(userId); 
    } 

    @RequestMapping(method = RequestMethod.POST, value="/mathify/signup") 
    public User register(@RequestBody User user){ 

     return userService.doSignup(user); 

    } 

    @GetMapping(value="/hi") 
    public String test(){ 

     return "Oh ! I am fine without secuirity"; 
    } 

} 

有了上面的代碼片段,我可以獲得access_token(/ oauth/token),並且我也可以調用其他控制器類私有API,而不會有任何問題。

但上述代碼存在問題。什麼?在上面的代碼片段中,用戶是硬編碼的,但是當我想在用戶註冊時獲取access_token時,它會發出異常。

2017-06-18 11:04:05.689 ERROR 8492 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.aut[email protected]6b66d7ac to already built object] with root cause 

java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.aut[email protected]6b66d7ac to already built object 
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.add(AbstractConfiguredSecurityBuilder.java:196) ~[spring-security-config-4.2.2.RELEASE.jar:4.2.2.RELEASE] 
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.apply(AbstractConfiguredSecurityBuilder.java:133) ~[spring-security-config-4.2.2.RELEASE.jar:4.2.2.RELEASE] 
    at org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.apply(AuthenticationManagerBuilder.java:290) ~[spring-security-config-4.2.2.RELEASE.jar:4.2.2.RELEASE] 
    at org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.userDetailsService(AuthenticationManagerBuilder.java:187) ~[spring-security-config-4.2.2.RELEASE.jar:4.2.2.RELEASE] 
    at com.techiesandeep.mathify.controller.LoginController.register(LoginController.java:40) ~[classes/:na] 

爲實現上述功能,我做我的應用程序和控制器

應用類的一些變化是由於: -

@SpringBootApplication 
public class MathifyApplication { 
    @Autowired 
    private PasswordEncoder passwordEncoder; 


    public static void main(String[] args) { 
     SpringApplication.run(MathifyApplication.class, args); 
    } 
} 

和控制器類是: -

@RestController 
public class LoginController { 
    @Autowired 
     private UserService userService; 
     @Autowired 
     AuthenticationManagerBuilder builder; 
     @Autowired 
     private PasswordEncoder passwordEncoder; 
     @Autowired 
     private UserRepository repository; 


     @RequestMapping(value = "/mathify/getuser/{userId}", method = RequestMethod.GET) 
     public User getUser(@PathVariable String userId){ 
      System.out.println("Userid "+userId); 
      return userService.getUser(userId); 
     } 

     @RequestMapping(method = RequestMethod.POST, value="/user/signup") 
     public User register(@RequestBody User user) throws Exception { 
      User u = userService.doSignup(user); 
      builder.userDetailsService(userDetailsService(repository)).passwordEncoder(passwordEncoder); 
      return u; 
     } 

     private UserDetailsService userDetailsService(final UserRepository repository) { 
      return userName -> new CustomUserDetails(repository.findByUsername(userName)); 
     } 

     @GetMapping(value="/hi") 
     public String test(){ 

      return "Oh ! I am fine without secuirity"; 
     } 
} 

任何幫助將是可觀的。謝謝

+0

要動態建立驗證管理。這是我第一次看到這個,我強烈建議不要這樣做。 – shazin

+0

@Shazin基本上我想給用戶成功註冊後使用其他API可以引導我嗎?我谷歌很多,但沒有得到任何有關的東西任何鏈接或任何guidence將有助於很多謝謝 –

+0

您可以請求oauth /令牌端點獲取訪問令牌。 – hunter09h

回答

1

您可以調用另一個POST請求來獲取訪問令牌。 我不確定這是最好的方式,但對我很好。內註冊請求映射

示例代碼剪斷:

RestTemplate restTemplate = new RestTemplate(); 
    HttpHeaders headers = new HttpHeaders(); 
    headers.setContentType(MediaType.APPLICATION_JSON); 
    headers.set("Authorization", auth_header); 
    /*auth_header should be Autorization header value that captured from signup request, which is generated by Basic Auth with clientID and secret, for example, "Basic bXktdHJ1c3RlZC1jbGllbnQ6c2VjcmV0" */ 
    HttpEntity<String> entity = new HttpEntity<String>("",headers); 
    String authURL = "http://localhost:8080/oauth/token?grant_type=password&username=yourusername&password=yourpassword"; 
    ResponseEntity<String> response = restTemplate.postForEntity(authURL, entity, String.class); 

    System.out.println(response.getBody()); 
相關問題