Как я могу защитить корни разными методами аутентификации?Форма входа и токен - PullRequest
0 голосов
/ 22 марта 2019

Я новичок в весенней загрузке и пытаюсь защитить свое приложение.

Я сделаю следующее: Маршрут "/ api / " должен быть защищен маркером доступа с oauth, а маршруты "/ user / " - обычным логином Basic-Auth Form.

Для этого у меня реализованы следующие классы

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Configuration
@Order(2)
public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${security.signing-key}")
    private String signingKey;

    @Value("${security.encoding-strength}")
    private Integer encodingStrength;

    @Value("${security.security-realm}")
    private String securityRealm;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable().authorizeRequests().antMatchers("/api/**").hasRole("admin").and().httpBasic()
                .authenticationEntryPoint(authenticationEntryPoint());
    }

    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
        entryPoint.setRealmName(securityRealm);
        return entryPoint;
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(signingKey);
        return converter;
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    @Primary 
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }
}

@Configuration
@Order(1)
public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter {
    private static final String LOGIN_PROCESSING_URL = "/login";
    private static final String LOGIN_FAILURE_URL = "/login?error";
    private static final String LOGIN_URL = "/login";
    private static final String LOGOUT_SUCCESS_URL = "/logout";
    private static final String LOGIN_SUCCESS_URL = "/user";


    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable() 
                .authorizeRequests() 
                .antMatchers("/user").hasAnyAuthority(Role.getAllRoles()).anyRequest().authenticated().and()                                                                
                .formLogin().loginPage("/login").permitAll().and() 
                .logout().permitAll();
    }


    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(

                //...)
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public User currentUser(UserRepository userRepository) {
        return userRepository.findByEmailIgnoreCase(SecurityUtils.getUsername());
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Bean()
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}
}

и

@Service
@Primary
public class UserDetailsServiceImpl implements UserDetailsService {

private final UserRepository userRepository;

@Autowired
public UserDetailsServiceImpl(UserRepository userRepository) {
    this.userRepository = userRepository;
}


@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userRepository.findByEmailIgnoreCase(username);
    if (null == user) {
        throw new UsernameNotFoundException("No user present with username: " + username);
    } else {

        List<GrantedAuthority> auths = new ArrayList<>();
        for(Role role: user.getRoles()) {
            auths.add(new SimpleGrantedAuthority(role.getName()));
        }
        Collection<? extends GrantedAuthority> authorities = auths;

        return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPasswordHash(),
                authorities);
    }
}
}

и

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends  AuthorizationServerConfigurerAdapter {

@Value("${security.jwt.client-id}")
   private String clientId;

   @Value("${security.jwt.client-secret}")
   private String clientSecret;

   @Value("${security.jwt.grant-type}")
   private String grantType;

   @Value("${security.jwt.scope-read}")
   private String scopeRead;

   @Value("${security.jwt.scope-write}")
   private String scopeWrite = "write";

   @Value("${security.jwt.resource-ids}")
   private String resourceIds;

   @Autowired
   private TokenStore tokenStore;

   @Autowired
   private JwtAccessTokenConverter accessTokenConverter;


@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private PasswordEncoder passwordEncoder;

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
   TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
   enhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
   endpoints.tokenStore(tokenStore)
           .accessTokenConverter(accessTokenConverter)
           .tokenEnhancer(enhancerChain)
           .authenticationManager(authenticationManager);
}

@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
   configurer
           .inMemory()
           .withClient(clientId)
           .secret(passwordEncoder.encode(clientSecret))
           .authorizedGrantTypes(grantType)
           .scopes(scopeRead, scopeWrite)
           .resourceIds(resourceIds);
}

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security
            .checkTokenAccess("isAuthenticated()")
            .allowFormAuthenticationForClients();
}

}

и

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

@Autowired
private ResourceServerTokenServices tokenServices;

@Value("${security.jwt.resource-ids}")
private String resourceIds;

@Override
public void configure(HttpSecurity http) throws Exception {

    http.requestMatchers().and().authorizeRequests()
    .antMatchers("/oauth/token").permitAll().antMatchers("/api/**").authenticated();

}

@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources.resourceId(resourceIds).tokenServices(tokenServices);
}
}

Путь "/ user" защищен входом в систему, но ресурс / api / test-Resource также защищен обычной формой входа. В / oauth / token я получаю токен доступа после запроса, как хочу.

Но как я могу сконфигурировать мои классы конфигурации, чтобы / api / ** был защищен токеном? И где я должен настроить пути, в WebSecurityConfig или в ResourceServerConfig? С сегодняшнего дня спички в обоих классах. Я не нашел хорошего учебника для своей особой Задачи.

...