@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

 

   @Autowired
    private CustClientDetailsService custClientDetailsService;

    @Autowired
    private CustClientAuthenticationProvider custClientAuthenticationProvider;

    /**
     * 配置客户端
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(custClientDetailsService);
    }

 

    /**
     * 配置令牌端点
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                .tokenKeyAccess(“permitAll()”)
                .checkTokenAccess(“isAuthenticated()”)
                .addTokenEndpointAuthenticationFilter(custClientCredentialsTokenEndpointFilter());//配置应用客户端认证过滤器
    }

    @Bean
    public CustClientCredentialsTokenEndpointFilter custClientCredentialsTokenEndpointFilter() {
        CustClientCredentialsTokenEndpointFilter custClientCredentialsTokenEndpointFilter = new CustClientCredentialsTokenEndpointFilter(“/oauth/token”);
        OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
        authenticationEntryPoint.setTypeName(“Form”);
        authenticationEntryPoint.setRealmName(“oauth2/client”);
        custClientCredentialsTokenEndpointFilter.setAuthenticationEntryPoint(authenticationEntryPoint);
        ProviderManager providerManager = new ProviderManager(Collections.singletonList(custClientAuthenticationProvider));
        custClientCredentialsTokenEndpointFilter.setAuthenticationManager(providerManager);
        return custClientCredentialsTokenEndpointFilter;
    }
}
 
 

@Component
public class CustClientAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private CustClientService custClientService;
   
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String clientId = authentication.getName();
        String clientSecret = authentication.getCredentials().toString();

        CustClient custClient = custClientService.getClientDetailsById(clientId);
        if (null == client) {
            throw new Exception(“client is null”);
        }

        if (custClient.isSecretRequired()) {
            if (!passwordEncoder.matches(clientSecret,custClient.getClientSecret())) {
                throw new Exception(“ClientSecret is error”);
            }
        }

        User user = new User(clientId, “”, new ArrayList<>());
        return new UsernamePasswordAuthenticationToken(user, “”, new ArrayList<>());
    }

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

    private boolean allowOnlyPost = false;

    public CustClientCredentialsTokenEndpointFilter() {
        this(“/oauth/token”);
    }

    public CustClientCredentialsTokenEndpointFilter(String path) {
        super(path);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, ServletException {
        if (allowOnlyPost && !”POST”.equalsIgnoreCase(request.getMethod())) {
            throw new HttpRequestMethodNotSupportedException(request.getMethod(), new String[]{“POST”});
        }
        String clientId = request.getParameter(“client_id”);

        String clientSecret = request.getParameter(“client_secret”) ? null : “” : clientSecret;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated()) {
            return authentication;
        }

        if (clientId == null) {
            throw new BadCredentialsException(“clientId is null”);
        }  
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId, clientSecret);
        return this.getAuthenticationManager().authenticate(authRequest);
    }
}

@Component
public class CustClientDetailsService implements ClientDetailsService, ClientRegistrationService {

    @Autowired
    private CustClientService custClientService;

    /**
     * 根据clientId查询客户端
     */
    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
        ClientDetails details;
        details = custClientService.getClientDetailsById(clientId);
        if (null == details) {
            throw new NoSuchClientException(“client is null”);
        }
        return details;
    }

    @Override
    public void addClientDetails(ClientDetails clientDetails) throws ClientAlreadyExistsException {

    }

    @Override
    public void updateClientDetails(ClientDetails clientDetails) throws NoSuchClientException {

    }

    @Override
    public void updateClientSecret(String clientId, String secret) throws NoSuchClientException {

    }

    @Override
    public void removeClientDetails(String clientId) throws NoSuchClientException {

    }

    @Override
    public List<ClientDetails> listClientDetails() {
        return null;
    }
}

@Service
public class CustClientService {
    @Autowire
    private ClientDao clientDao;
 
    /**
     * 根据clientId查询客户端
     */
    public ClientDetails  getClientDetailsById(String clientId) {
        CustClient client = findClientByClientId(clientId);
        if (null == client) {
            throw new Exception(“client is null”);
        }
        ClientDetails clientDetails = CustClientDetails.convertTo(client);
        return clientDetails;
    }

    /**
     * 根据clientId查询客户端
     */
    public CustClient findClientByClientId(String clientId) {
        return clientDao.findClientByClientId(clientId);
    }
}
 
 
public class CustClientDetails implements ClientDetails, Serializable {
//省略
}