Rest API: 基本认证和摘要认证

来源:互联网 发布:中国js 12.7mm狙击步枪 编辑:程序博客网 时间:2024/05/20 03:07

用spring security实现Rest API的基本认证(Basic)和摘要认证(Digest):

Basic 认证

1. server - spring security配置

package com.pechen.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {     public final static String REALM="MY_REALM";         @Autowired    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN")        .and().withUser("test").password("test").roles("USER");    }         @Override    protected void configure(HttpSecurity http) throws Exception {    http.csrf().disable()        .authorizeRequests()        .anyRequest().authenticated()        .and().httpBasic().realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint());//        .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//We don't need sessions to be created.    }        @Bean    public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint(){        return new CustomBasicAuthenticationEntryPoint();    }        @Bean    public AuthenticationManager authenticationManagerBean() throws Exception {        // altough this seems like useless code,        // its required to prevend spring boot auto-configuration        return super.authenticationManagerBean();    }}
package com.pechen.config;import java.io.IOException;import java.io.PrintWriter; import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse; import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; public class CustomBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint { @Overridepublic void commence(final HttpServletRequest request, final HttpServletResponse response,final AuthenticationException authException) throws IOException, ServletException {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\"");PrintWriter writer = response.getWriter();writer.println("HTTP Status 401 : " + authException.getMessage());}@Overridepublic void afterPropertiesSet() throws Exception {setRealmName(WebSecurityConfig.REALM);super.afterPropertiesSet();}}

2. server - rest api

package com.pechen.rest;import java.util.Map;import org.springframework.web.bind.annotation.RequestHeader;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;/** * Authentication service. */@RestController@RequestMapping(path = "/")public class RestService {    @RequestMapping(path = "/login", method = RequestMethod.GET)    public String login(@RequestHeader Map<String, Object> headers){    return "Login success...";    }}

3. client - rest template(加上Authorization的头部即可)

package com.pechen.test;import java.util.Base64;import org.junit.Test;import org.springframework.http.HttpEntity;import org.springframework.http.HttpHeaders;import org.springframework.http.HttpMethod;import org.springframework.http.ResponseEntity;import org.springframework.web.client.RestTemplate;public class AuthServiceTest {private HttpHeaders getHeaders(){String plainCredentials="admin:admin";String base64Credentials = Base64.getEncoder().encodeToString(plainCredentials.getBytes());HttpHeaders headers = new HttpHeaders();headers.add("Authorization", "Basic " + base64Credentials);return headers;}@Testpublic void testLogin() {RestTemplate restTemplate = new RestTemplate();HttpEntity<String> request = new HttpEntity<String>(getHeaders());ResponseEntity<String> response = restTemplate.exchange("http://localhost:8080/login", HttpMethod.GET,request, String.class);System.out.println(response.getBody());}}

Digest 认证

1. server - spring security配置

package com.pechen.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.config.http.SessionCreationPolicy;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.web.authentication.www.DigestAuthenticationFilter; @Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {     public final static String REALM="MY_REALM";         @Autowired    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN")        .and().withUser("test").password("test").roles("USER");    }         @Override    protected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().exceptionHandling().authenticationEntryPoint(getDigestEntryPoint()).and().addFilter(getDigestAuthenticationFilter(getDigestEntryPoint()));        }    @Beanpublic MyDigestAuthenticationEntryPoint getDigestEntryPoint() {MyDigestAuthenticationEntryPoint digestAuthenticationEntryPoint = new MyDigestAuthenticationEntryPoint();digestAuthenticationEntryPoint.setKey("mykey");digestAuthenticationEntryPoint.setNonceValiditySeconds(120);digestAuthenticationEntryPoint.setRealmName(REALM);return digestAuthenticationEntryPoint;}public DigestAuthenticationFilter getDigestAuthenticationFilter(MyDigestAuthenticationEntryPoint digestAuthenticationEntryPoint) throws Exception {DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();digestAuthenticationFilter.setAuthenticationEntryPoint(digestAuthenticationEntryPoint);digestAuthenticationFilter.setUserDetailsService(userDetailsServiceBean());return digestAuthenticationFilter;} @Override@Beanpublic UserDetailsService userDetailsServiceBean() throws Exception {return super.userDetailsServiceBean();}}
package com.pechen.config;import org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint;public class MyDigestAuthenticationEntryPoint extends DigestAuthenticationEntryPoint {@Overridepublic void afterPropertiesSet() throws Exception{super.afterPropertiesSet();setRealmName(WebSecurityConfig.REALM);}}
2. server - rest api 同上
3. client - 配置rest template使用Digest认证

package com.pechen.rest;import org.apache.http.auth.AuthScope;import org.apache.http.auth.UsernamePasswordCredentials;import org.apache.http.client.CredentialsProvider;import org.apache.http.impl.client.BasicCredentialsProvider;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClientBuilder;import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;import org.springframework.web.client.RestTemplate;public class RestTempleteConfig {public RestTemplate getRestTemplate() {CloseableHttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider()).useSystemProperties().build();HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactoryDigestAuth(client);return new RestTemplate(requestFactory);}private CredentialsProvider provider() {CredentialsProvider provider = new BasicCredentialsProvider();UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("admin", "admin");provider.setCredentials(AuthScope.ANY, credentials);return provider;}}
package com.pechen.rest;import java.net.URI;import org.apache.http.HttpHost;import org.apache.http.client.AuthCache;import org.apache.http.client.HttpClient;import org.apache.http.client.protocol.ClientContext;import org.apache.http.impl.auth.DigestScheme;import org.apache.http.impl.client.BasicAuthCache;import org.apache.http.protocol.BasicHttpContext;import org.apache.http.protocol.HttpContext;import org.springframework.http.HttpMethod;import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;public class HttpComponentsClientHttpRequestFactoryDigestAuth extends HttpComponentsClientHttpRequestFactory {     public HttpComponentsClientHttpRequestFactoryDigestAuth(HttpClient client) {        super(client);    }     @Override    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {        return createHttpContext(uri);    }     private HttpContext createHttpContext(URI uri) {        // Create AuthCache instance        AuthCache authCache = new BasicAuthCache();        // Generate DIGEST scheme object, initialize it and add it to the local auth cache        DigestScheme digestAuth = new DigestScheme();        // If we already know the realm name        digestAuth.overrideParamter("realm", "myrealm");        HttpHost targetHost = new HttpHost(uri.getHost(), uri.getPort());        authCache.put(targetHost, digestAuth);         // Add AuthCache to the execution context        BasicHttpContext localcontext = new BasicHttpContext();        localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);        return localcontext;    }}
4. 使用rest template发送请求

package com.pechen.test;import org.junit.Test;import org.springframework.http.HttpMethod;import org.springframework.http.ResponseEntity;import org.springframework.web.client.RestTemplate;import jdk.nashorn.internal.ir.annotations.Ignore;public class RestClient {@Testpublic void whenSecuredRestApiIsConsumed_then200OK() {    RestTemplate restTemplate = new RestTempleteConfig().getRestTemplate();    String uri = "http://localhost:8080/login";    ResponseEntity<String> entity = restTemplate.exchange(uri, HttpMethod.GET, null, String.class);    System.out.println(entity.getStatusCode());    System.out.println(entity.getBody());}}








0 0
原创粉丝点击