上两篇介绍了环境配置和用户密码模式,下面介绍授权码模式。
git地址:https://gitee.com/xiaoyaofeiyang/OauthUmp
spring Security4 和 oauth2整合 注解+xml混合使用(基础运行篇)
spring Security4 和 oauth2整合 注解+xml混合使用(进阶篇)
spring Security4 和 oauth2整合 注解+xml混合使用(授权码篇)
spring Security4 和 oauth2整合 注解+xml混合使用(注意事项篇)
spring Security4 和 oauth2整合 注解+xml混合使用(替换6位的授权码)
spring Security4 和 oauth2整合 注解+xml混合使用(替换用户名密码认证)
spring Security4 和 oauth2整合 注解+xml混合使用(验证码等额外数据验证)
授权码模式需要对OAuth2SecurityConfiguration进行一些配置,对跳转的url做限制。
package com.ump.test.oauth;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;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.core.userdetails.UserDetailsService;import org.springframework.security.oauth2.provider.ClientDetailsService;import org.springframework.security.oauth2.provider.approval.ApprovalStore;import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;import org.springframework.security.oauth2.provider.token.TokenStore;import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;@Configuration@EnableWebSecuritypublic class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired @Qualifier("myClientDetailsService") private ClientDetailsService clientDetailsService;// @Autowired// @Qualifier("myUserDetailsService")// private UserDetailsService userDetailsService; @Autowired public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { //auth.userDetailsService(userDetailsService); auth.inMemoryAuthentication() .withUser("bill").password("abc123").roles("ADMIN").and() .withUser("bob").password("abc123").roles("USER"); } @Override public void configure(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .antMatchers("/oauth/token") .permitAll().and() .formLogin().loginPage("/authlogin.jsp") .usernameParameter("userName").passwordParameter("userPwd") .loginProcessingUrl("/login").failureUrl("/index1.jsp") .and().logout().logoutUrl("/logout"); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); }//// @Bean// public TokenStore tokenStore() {// return new InMemoryTokenStore();// } @Bean @Autowired public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){ TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler(); handler.setTokenStore(tokenStore); handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService)); handler.setClientDetailsService(clientDetailsService); return handler; } @Bean @Autowired public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception { TokenApprovalStore store = new TokenApprovalStore(); store.setTokenStore(tokenStore); return store; }}
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><%@ page language="java" pageEncoding="UTF-8"%> <head><% String baseUrl = request.getContextPath();%><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><script type="text/javascript" src="<%=baseUrl%>/js/jquery-3.2.1.min.js"></script><title>SkyNet</title></head><script type="text/javascript"> function ajaxTest() { var type = "1"; $.ajax({ type : "post", url : "<%=baseUrl%>/test/welCome", dataType : "json", data : {reqType : type} , success : function(data) { $("#div1").html(data.uuid + "<br>" + data.welMsg + "<br>"+ data.dateTime); }, error : function(XMLHttpRequest, textStatus, errorThrown) { alert(errorThrown); } }); }</script><body> 这里是htm1 <div id="div1"></div> <button type="button" onclick="ajaxTest()">Welcome</button> <form action="<%=baseUrl%>/login" method="post">First name:<br><input type="text" name="userName"><br>Last name:<br><input type="text" name="userPwd"><input type="submit" value="Submit" /></form> <script type="text/javascript"> $(document).ready(function() { $("#div1").html("呵呵"); }); </script></body></html>
加上前面两篇的测试页面,这样授权码模式就可以了。不过还有个问题,就是授权码的client_id必须用baseauth的方式去写,不能直接写在链接里,这就很烦人。想写在链接里,很简单,AuthorizationServerConfiguration加上一句oauthServer.allowFormAuthenticationForClients();即可。
package com.ump.test.oauth;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;import org.springframework.security.oauth2.provider.ClientDetailsService;import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;import org.springframework.security.oauth2.provider.token.TokenStore;@Configuration@EnableAuthorizationServerpublic class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { private static String REALM = "MY_OAUTH_REALM"; @Autowired private TokenStore tokenStore; @Autowired @Qualifier("myClientDetailsService") private ClientDetailsService clientDetailsService; @Autowired private UserApprovalHandler userApprovalHandler; @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.withClientDetails(clientDetailsService);// clients.inMemory().withClient("my-trusted-client")// .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")// .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT").scopes("read", "write", "trust").secret("secret")// .accessTokenValiditySeconds(120)// .refreshTokenValiditySeconds(600); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler) .authenticationManager(authenticationManager); } @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.allowFormAuthenticationForClients(); oauthServer.realm(REALM + "/client"); }}
oauth2的授权页面太丑了,可以考虑改一下,找个最简单的方案即可。我这里页面跟它类似,也很丑,就是copy它的,做个示范。
package com.ump.test.oauth;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.SessionAttributes;@Controller@SessionAttributes("authorizationRequest")public class OAuth2ApprovalController { @RequestMapping("/oauth/confirm_access") public String getAccessConfirmation(Map<String, Object> model, HttpServletRequest request) throws Exception { return "/user/oauth_approval.jsp"; }}
<%@ page language="java" pageEncoding="UTF-8"%> <html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>授权</title></head><body> <h1>自定义 Approval</h1> <p>这是我自己的,怎么样?</p> <form id='confirmationForm' name='confirmationForm' action='/oauth/authorize' method='post'> <input name='user_oauth_approval' value='true' type='hidden' /><label><input name='authorize' value='Authorize' type='submit' /></label> </form> <form id='denialForm' name='denialForm' action='/oauth/authorize' method='post'> <input name='user_oauth_approval' value='false' type='hidden' /><label><input name='deny' value='Deny' type='submit' /></label> </form></body></html>
可以咯,下一篇写个注意事项。
联系客服