这是我如何通过Java Config在spring-boot 1.1.4中获得0腿OAuth 1.0的工作方式。
注意:就我而言,我只希望OAuth保护单个路径(/ oauth /
**),因此,如果希望保护所有内容,则可以简化其中的某些部分。您可以在这里查看我的完整代码:https://github.com/azeckoski/lti_starter
一旦拥有了下面显示的最少部分,您就应该能够运行spring-boot应用程序,并使用ConsumerKey:key和Secret:secret在/
oauth处触发OAuth 1.0兼容请求,并成功加载路径。
应用程序
重要说明
:(1)不要只是将ZeroLeggedOAuthProviderProcessingFilter声明为Bean,否则将影响所有路径(它将自动被spring拾取)。(2)如果要访问,则必须存在NoAuthConfigurationAdapter受保护路径之外的安全数据(在本例中为/
oauth)
@ComponentScan@Configuration@EnableAutoConfiguration@EnableWebMvcSecurity // enable spring security and web mvc hooks@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)public class Application extends WebMvcConfigurerAdapter { final static Logger log = LoggerFactory.getLogger(Application.class); public static void main(String[] args) { SpringApplication.run(Application.class, args); } // Spring Security @Autowired @Order(Ordered.HIGHEST_PRECEDENCE + 10) @SuppressWarnings("SpringJavaAutowiringInspection") public void configureSimpleAuthUsers(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin").password("admin").roles("ADMIN", "USER") .and().withUser("user").password("user").roles("USER"); } @Configuration @Order(1) // HIGHEST public static class OAuthSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { private ZeroLeggedOAuthProviderProcessingFilter zeroLeggedOAuthProviderProcessingFilter; @Autowired OAuthConsumerDetailsService oauthConsumerDetailsService; @Autowired OAuthAuthenticationHandler oauthAuthenticationHandler; @Autowired OAuthProcessingFilterEntryPoint oauthProcessingFilterEntryPoint; @Autowired OAuthProviderTokenServices oauthProviderTokenServices; @PostConstruct public void init() { zeroLeggedOAuthProviderProcessingFilter = new ZeroLeggedOAuthProviderProcessingFilter(oauthConsumerDetailsService, new InMemoryNonceServices(), oauthProcessingFilterEntryPoint, oauthAuthenticationHandler, oauthProviderTokenServices); } @Override protected void configure(HttpSecurity http) throws Exception { http.antMatcher("/oauth/**") .addFilterBefore(zeroLeggedOAuthProviderProcessingFilter, UsernamePasswordAuthenticationFilter.class) .authorizeRequests().anyRequest().hasRole("OAUTH"); } } @Order(45) // LOW @Configuration public static class BasicAuthConfigurationAdapter extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.antMatcher("/basic/**").authorizeRequests().anyRequest().authenticated() .and().httpBasic(); } } @Order(67) // LOWEST @Configuration public static class NoAuthConfigurationAdapter extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.antMatcher("/**").authorizeRequests().anyRequest().permitAll(); } } // OAuth beans public static class OAuthProcessingFilterEntryPointImpl extends OAuthProcessingFilterEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { log.info("OAuth FILTER Failure (commence), req=" + request + ", ex=" + authException); // Called when there is an OAuth Auth failure, authException may be InsufficientAuthenticationException super.commence(request, response, authException); } } @Bean(name = "oauthAuthenticationEntryPoint") public OAuthProcessingFilterEntryPoint oauthAuthenticationEntryPoint() { return new OAuthProcessingFilterEntryPointImpl(); } @Bean(name = "oauthProviderTokenServices") public OAuthProviderTokenServices oauthProviderTokenServices() { // NOTE: we don't use the OAuthProviderTokenServices for 0-legged but it cannot be null return new InMemoryProviderTokenServices(); } public static class ZeroLeggedOAuthProviderProcessingFilter extends ProtectedResourceProcessingFilter { ZeroLeggedOAuthProviderProcessingFilter(OAuthConsumerDetailsService oAuthConsumerDetailsService, OAuthNonceServices oAuthNonceServices, OAuthProcessingFilterEntryPoint oAuthProcessingFilterEntryPoint, OAuthAuthenticationHandler oAuthAuthenticationHandler, OAuthProviderTokenServices oAuthProviderTokenServices) { super(); log.info("ConSTRUCT Zero Legged OAuth provider"); setAuthenticationEntryPoint(oAuthProcessingFilterEntryPoint); setAuthHandler(oAuthAuthenticationHandler); setConsumerDetailsService(oAuthConsumerDetailsService); setNonceServices(oAuthNonceServices); setTokenServices(oAuthProviderTokenServices); //setIgnoreMissingCredentials(false); // die if OAuth params are not included } }}OAuthConsumerDetailsService.java
@Componentpublic class OAuthConsumerDetailsService implements ConsumerDetailsService { final static Logger log = LoggerFactory.getLogger(OAuthConsumerDetailsService.class); @Override public ConsumerDetails loadConsumerByConsumerKey(String consumerKey) throws OAuthException { baseConsumerDetails cd; // NOTE: really lookup the key and secret, for the sample here we just hardpred if ("key".equals(consumerKey)) { // allow this oauth request cd = new baseConsumerDetails(); cd.setConsumerKey(consumerKey); cd.setSignatureSecret(new SharedConsumerSecretImpl("secret")); cd.setConsumerName("Sample"); cd.setRequiredToObtainAuthenticatedToken(false); // no token required (0-legged) cd.getAuthorities().add(new SimpleGrantedAuthority("ROLE_OAUTH")); // add the ROLE_OAUTH (can add others as well) log.info("OAuth check SUCCESS, consumer key: " + consumerKey); } else { // deny - failed to match throw new OAuthException("For this example, key must be 'key'"); } return cd; }}MyOAuthAuthenticationHandler.java
最后一部分对于根据来自OAuth请求的数据定义实际用户(和Principal)很重要。这将取决于您在本地处理事物的方式而有所不同,但这是如何执行此操作的示例。
@Componentpublic class MyOAuthAuthenticationHandler implements OAuthAuthenticationHandler { final static Logger log = LoggerFactory.getLogger(MyOAuthAuthenticationHandler.class); static SimpleGrantedAuthority userGA = new SimpleGrantedAuthority("ROLE_USER"); static SimpleGrantedAuthority adminGA = new SimpleGrantedAuthority("ROLE_ADMIN"); @Override public Authentication createAuthentication(HttpServletRequest request, ConsumerAuthentication authentication, OAuthAccessProviderToken authToken) { Collection<GrantedAuthority> authorities = new HashSet<>(authentication.getAuthorities()); // attempt to create a user Authority String username = request.getParameter("username"); if (StringUtils.isBlank(username)) { username = authentication.getName(); } // NOTE: you should replace this block with your real rules for determining OAUTH ADMIN roles if (username.equals("admin")) { authorities.add(userGA); authorities.add(adminGA); } else { authorities.add(userGA); } Principal principal = new NamedOAuthPrincipal(username, authorities, authentication.getConsumerCredentials().getConsumerKey(), authentication.getConsumerCredentials().getSignature(), authentication.getConsumerCredentials().getSignatureMethod(), authentication.getConsumerCredentials().getSignaturebaseString(), authentication.getConsumerCredentials().getToken() ); Authentication auth = new UsernamePasswordAuthenticationToken(principal, null, authorities); return auth; } public static class NamedOAuthPrincipal extends ConsumerCredentials implements Principal { public String name; public Collection<GrantedAuthority> authorities; public NamedOAuthPrincipal(String name, Collection<GrantedAuthority> authorities, String consumerKey, String signature, String signatureMethod, String signaturebaseString, String token) { super(consumerKey, signature, signatureMethod, signaturebaseString, token); this.name = name; this.authorities = authorities; } @Override public String getName() { return name; } public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; } }}OAuthController.java
@Controller@RequestMapping("/oauth")public class OAuthController extends baseController { @RequestMapping({"", "/"}) public String home(HttpServletRequest req, Principal principal, Model model) { return "home"; // name of the template }}pom.xml(maven-仅关键部分)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><!-- security and oauth --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId></dependency><!-- OAuth --><dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth</artifactId> <version>2.0.2.RELEASE</version></dependency>



