本文介绍了用户在springboot中调用signup rest API时如何获取oAuth2访问令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在研究 Springboot 安全性,这对我来说是全新的.我关注了 youtube 视频教程 视频

currently I am working on Springboot security, its quite new for me. I followed youtube video tutorial Video

当我使用以下代码片段时,我成功获得了 oauth2 access_token:-

I am getting oauth2 access_token successfully when I use bellow code snippet:-

@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", "abc@gmail.com", "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.

With above code snippet I can get access_token(/oauth/token), and I can also call other controller class private APIs without any issue.

但是上面的代码有问题.什么?在上面的代码片段中,用户是硬编码的,但是当我想在用户注册时获取 access_token 时,它给出了一个例外.

but there is a problem with above code. What? In above code snippet User is hard coded, but when I want to get access_token at the time of user signup it's giving an exception.

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.authentication.configurers.userdetails.DaoAuthenticationConfigurer@6b66d7ac to already built object] with root cause

java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer@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]

为了实现上述功能,我对应用程序和控制器进行了一些更改

for achieving above described feature I did some changes in my Application and Controller

应用程序类为:-

@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";
        }
}

任何帮助都是可观的.谢谢

Any help would be appreciable.thanks

推荐答案

您可以调用另一个 POST 请求来获取访问令牌.我不确定这是最好的方法,但对我来说效果很好.

You can call another POST request to get access token.I am not sure it's the best way, but worked fine with me.

注册请求映射中的示例代码片段:

Example code snip inside Signup Request mapping:

    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());

这篇关于用户在springboot中调用signup rest API时如何获取oAuth2访问令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-26 17:22