복붙노트

[SPRING] Spring 보안 및 Java 구성을 사용하는 사용자 정의 인증 관리자

SPRING

Spring 보안 및 Java 구성을 사용하는 사용자 정의 인증 관리자

SpringMVC와 함께 Spring Security를 ​​사용하여 기존 애플리케이션 (이 기사에서는 BackendApp로 지칭함)과 통신하는 웹 애플리케이션 (명확성을 위해 WebApp이라고 부름)을 작성합니다.

BackendApp에 인증 책임을 위임하고 싶습니다 (두 응용 프로그램을 동기화 할 필요가 없도록).

이를 구현하기 위해 WebApp (실행중인 스프링 보안)은 폼에서 사용자가 제공 한 사용자 이름과 암호로 REST를 통해 BackendApp과 통신하고 BackendApp의 응답이 200 OK인지 401 Unauthorized인지에 따라 인증하도록합니다.

이 작업을 수행하기 위해 사용자 지정 인증 관리자를 작성해야한다는 것을 이해하지만, 봄에 익숙하지 않으며이를 구현하는 방법에 대한 정보를 찾을 수 없습니다.

나는 이렇게 할 필요가 있다고 믿는다.

public class CustomAuthenticationManager implements AuthenticationManager{

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        String username = authentication.getName();
        String pw       = authentication.getCredentials().toString();

        // Code to make rest call here and check for OK or Unauthorised.
        // What do I return?

    }

}

성공하면 authentication.setAuthenticated (true)를 설정하고 그렇지 않으면 false를 설정합니까?

이것이 작성되면, Java 구성 파일을 사용하여이 인증 관리자를 사용하도록 스프링 보안을 어떻게 구성합니까?

도움을 주셔서 미리 감사드립니다.

해결법

  1. ==============================

    1.아래 샘플을보십시오. UsernamePasswordAuthenticationToken을 반환해야합니다. 주체와 GrantedAuthorities를 포함합니다. 희망은 내가 도울 수 :)

    아래 샘플을보십시오. UsernamePasswordAuthenticationToken을 반환해야합니다. 주체와 GrantedAuthorities를 포함합니다. 희망은 내가 도울 수 :)

    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getPrincipal() + "";
        String password = authentication.getCredentials() + "";
    
        User user = userRepo.findOne(username);
        if (user == null) {
            throw new BadCredentialsException("1000");
        }
        if (user.isDisabled()) {
            throw new DisabledException("1001");
        }
        if (!encoder.matches(password, user.getPassword())) {
            throw new BadCredentialsException("1000");
        }
        List<Right> userRights = rightRepo.getUserRights(username);
        return new UsernamePasswordAuthenticationToken(username, password, userRights.stream().map(x -> new SimpleGrantedAuthority(x.getName())).collect(Collectors.toList()));
    }
    

    추신 : userRepo와 rightRepo는 내 사용자 정의 User-DB에 액세스하는 Spring-Data-JPA 리포지토리입니다.

    스프링 보안 Java Config :

    @Configuration
    @EnableWebMvcSecurity
    public class MySecurityConfiguration extends WebSecurityConfigurerAdapter {
    
    public MySecurityConfiguration() {
        super(false);
    }
    
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return new ProviderManager(Arrays.asList((AuthenticationProvider) new AuthProvider()));
    }
    
    }
    
  2. ==============================

    2.그것의 가장 간단한 것에서 :

    그것의 가장 간단한 것에서 :

    @Override
        public Authentication authenticate(Authentication auth) throws AuthenticationException {
            String username = auth.getName();
            String password = auth.getCredentials().toString();
            // to add more logic
            List<GrantedAuthority> grantedAuths = new ArrayList<>();
            grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
            return new UsernamePasswordAuthenticationToken(username, password, grantedAuths);
        }
    
  3. ==============================

    3.먼저 사용자 정의 AuthenticationProvider를 사용하도록 Spring 보안을 구성해야합니다. 따라서 spring-security.xml (또는 동등한 구성 파일)에서 클래스가이 기능을 구현할 것을 정의해야합니다. 예 :

    먼저 사용자 정의 AuthenticationProvider를 사용하도록 Spring 보안을 구성해야합니다. 따라서 spring-security.xml (또는 동등한 구성 파일)에서 클래스가이 기능을 구현할 것을 정의해야합니다. 예 :

    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="myAuthenticationProvider" />
    </authentication-manager>
    
    <!-- Bean implementing AuthenticationProvider of Spring Security -->
    <beans:bean id="myAuthenticationProvider" class="com.teimas.MyAutenticationProvider">
    </beans:bean>
    

    두 번째로 당신은 당신의 예제에서와 같이 AuthenticationProvider를 구현해야한다. 특히 나머지 호출이 있어야하는 인증 방법 (인증 인증)입니다. 예 :

    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        User user = null;
        try {
            //use a rest service to find the user. 
            //Spring security provides user login name in authentication.getPrincipal()
                user = userRestService.loadUserByUsername(authentication.getPrincipal().toString());
        } catch (Exception e) {
            log.error("Error loading user, not found: " + e.getMessage(), e);
        }
    
        if (user == null) {
            throw new UsernameNotFoundException(String.format("Invalid credentials", authentication.getPrincipal()));
        } else if (!user.isEnabled()) {
            throw new UsernameNotFoundException(String.format("Not found enabled user for username ", user.getUsername()));
        }
        //check user password stored in authentication.getCredentials() against stored password hash
        if (StringUtils.isBlank(authentication.getCredentials().toString())
            || !passwordEncoder.isPasswordValid(user.getPasswordHash(), authentication.getCredentials().toString()) {
            throw new BadCredentialsException("Invalid credentials");
        }
    
        //doLogin makes whatever is necesary when login is made (put info in session, load other data etc..)
        return doLogin(user);
    } 
    
  4. ==============================

    4.내 솔루션은 첫 번째 답변과 거의 같습니다.

    내 솔루션은 첫 번째 답변과 거의 같습니다.

    1) 인증 공급자를 구현하는 클래스가 필요합니다.

    @Service
    @Configurable
    public class CustomAuthenticationProvider implements AuthenticationProvider    {
          @Override
          public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // Your code of custom Authentication
    }
    }
    

    2) 첫 x 째 대답에} 대하면이 사용자 정의 제공자 만 있으면 WebSecurityConfiguration에 다음 코드가 필요하지 않습니다.

    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
         return new ProviderManager(Arrays.asList((AuthenticationProvider) new  AuthProvider()));
    }
    

    문제는 Spring이 사용 가능한 공급자를 찾고 아무것도 발견되지 않으면 기본값을 사용한다는 것입니다. 그러나 AuthenticationProvider 구현이 있으면 구현이 사용됩니다.

  5. from https://stackoverflow.com/questions/31826233/custom-authentication-manager-with-spring-security-and-java-configuration by cc-by-sa and MIT license