Как настроить вход / аутентификацию с помощью Angular + Spring + JSON - PullRequest
2 голосов
/ 03 августа 2020

У меня есть интерфейс angular 7 и бэкэнд Spring.

Моя цель - создать собственный вход с использованием формы JSON. План: отправить логин / пароль из внешнего интерфейса в бэкенд в форме json. Выполните аутентификацию в бэкэнде и отправьте результат во внешний интерфейс. Моя проблема: после отправки данных из внешнего интерфейса я не вижу данные в серверной части (имя пользователя и пароль пусты) (в моем CustomAuthenticationProvider. java)

Функция моей страницы входа:

let credential = {username: this.loginForm.value.username, password: this.loginForm.value.password};

if(this.loginForm.value.username != null && this.loginForm.value.password != null) {
     this.http.post("auth", JSON.stringify(credential)).subscribe(
           response => {
                if(response.status == 200 && response.ok == true) {
                   this.globals.loggeduser = this.loginForm.value.username;
                   //and routing
                } else {
                     alert("Bad credential");
           } 
     );
}
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    public CustomAuthenticationProvider() {
        super();
    }

    @Override
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
        final String username = authentication.getName();
        final String password = authentication.getCredentials().toString();

 //THE PROBLEM: username and password are empty here

            if (/* some custom auth here */) {
                final List<GrantedAuthority> grantedAuths = new ArrayList<>();
                grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
                final UserDetails principal = new User(username, password, grantedAuths);
                final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths);
             
                return auth;
            }

        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }

}
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customAuthenticationProvider);
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers(HttpMethod.GET,"/login", "/index*", "/static/**", "/*.js", 
                                        "/*.json", "/*.ico", "/*.sccs", "/*.woff2", "/*.css").permitAll()
            .anyRequest()
                .authenticated()
                .and()
            .formLogin()
                .loginPage("/")
                .loginProcessingUrl("/auth")
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(successHandler())
                .failureHandler(failureHandler())
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    private AuthenticationSuccessHandler successHandler() {
       ...
    }

    private AuthenticationFailureHandler failureHandler() {
       ...
    }
}

Когда я распечатываю authentication после добавления значений к имени пользователя и паролю, я получаю следующее (основной и учетные данные пусты):

org.springframework.security.authentication.UsernamePasswordAuthenticationToken@b37b: Principal: ; Credentials: [PROTECTED];
Authenticated: false; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364:
RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Not granted any authorities

Использование not * Формат 1027 * работает нормально, но мне нужно использовать формат JSON. Я прочитал это и это (пробовал эти решения, не сработало). Они немного устарели и не очень хороши (слишком сложные и / или в формате xml). Я читал о том, что мне нужно написать собственный UsernamePasswordAuthenticationFilter / с использованием Beans, но я хотел бы создать хорошее и чистое решение java без переработка всего / с использованием xml. Могу ли я получить помощь / подсказки, пожалуйста?

Изменить: при использовании этого формата (вместо let credential = ... ) он работает (но, к сожалению, не JSON):

let urlSearchParams = new URLSearchParams();
urlSearchParams.append('username', this.loginForm.value.username );
urlSearchParams.append('password', this.loginForm.value.password );

1 Ответ

0 голосов
/ 06 августа 2020

Я нашел решение.

Я добавил CustomAuthenticationFilter, кредиты go на ответ @ oe.elvik в этом вопросе. (примечание: LoginRequest - это класс с двумя переменными: имя пользователя и пароль) После этого я добавил это в свой securityConfig, и все работает:

@Bean
public CustomAuthenticationFilter customAuthenticationFilter() throws Exception{
    CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter();
    customAuthenticationFilter.setAuthenticationManager(authenticationManager());
    customAuthenticationFilter.setFilterProcessesUrl("/auth");
    customAuthenticationFilter.setAuthenticationSuccessHandler(successHandler());
    customAuthenticationFilter.setAuthenticationFailureHandler(failureHandler());

    return customAuthenticationFilter;
}
...