Как получить токен доступа oAuth2, когда пользователь вызывает остаточный API регистрации в springboot?

в настоящее время я работаю над безопасностью Springboot, это совершенно новое для меня. Я следил за видеоруководством YouTube видео

Я успешно получаю 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.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]

для достижения описанной выше функции я внес некоторые изменения в свое приложение и контроллер.

Класс приложения: -

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

Любая помощь будет заметна. Спасибо


person Sandeep Tiwari    schedule 18.06.2017    source источник
comment
Вы строите Authentication Manager динамически. Впервые такое вижу и настоятельно не рекомендую этого делать.   -  person shazin    schedule 18.06.2017
comment
@Shazin По сути, я хочу дать токен пользователю после успешной регистрации с помощью rest API, можете ли вы мне помочь? Я много гуглил для этого, но не получил никаких релевантных вещей, любая ссылка ИЛИ любое руководство было бы полезно, спасибо   -  person Sandeep Tiwari    schedule 18.06.2017
comment
Вы можете запросить конечную точку oauth/token для получения токена доступа.   -  person Kevin    schedule 14.12.2017


Ответы (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());
person Kevin    schedule 14.12.2017