`

Spring Security oAuth学习之Hello World

阅读更多
OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。

OAUTH有1.0和2.0两个版本,2.0版本在1.0版本的基础上做了很多调整和改进,但目前尚不完善。

Spring Secrutiy的大名相信大家都应该有所了解,新的Spring Security版本对oAuth1.0有了完美的支持,支持oAuth2.0的版本目前正在开发过程中。

Spring Security官网上给出的sparklr和tonr的样例对于象笔者这样的初学者可能还是有点难以理解,所以我把学习过程中自己设计的一个Hello World的例子整理了一下与大家分享。

Server端的web.xml:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/security</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/oauth/*</url-pattern>
</servlet-mapping>



下面是spring mvc配置(/WEB-INF/spring-servlet.xml):

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean name="/security" class="com.coolfancy.oauth.server.SecurityController" />
<bean name="/confirm_access" class="com.coolfancy.oauth.server.ConfirmationController">
<property name="tokenServices" ref="tokenServices" />
<property name="consumerDetailsService" ref="consumerDetails" />
</bean>



下面是spring security的配置(/WEB-INF/spring-security.xml):


<http auto-config='true' access-denied-page="/public/index">
<intercept-url pattern="/security" access="ROLE_USER" />
<intercept-url pattern="/oauth/**" access="ROLE_USER" />
<intercept-url pattern="/request_token_authorized.jsp" access="ROLE_USER" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
</http>
<authentication-provider>
<user-service>
<user name="a" password="a" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
<oauth:provider
consumer-details-service-ref="consumerDetails"
token-services-ref="tokenServices"
request-token-url="/oauth/request_token"
authenticate-token-url="/oauth/authorize"
authentication-failed-url="/oauth/confirm_access"
access-granted-url="/request_token_authorized.jsp"
access-token-url="/oauth/access_token"
require10a="false" />
<oauth:consumer-details-service id="consumerDetails">
<oauth:consumer name="Fancy"
key="fancy-consumer-key"
secret="SHHHHH!!!!!!!!!!"
resourceName="Your Secrect"
resourceDescription="Your Secrect Response!" />
</oauth:consumer-details-service>
<oauth:token-services id="tokenServices" />


ConfirmationController:

package com.coolfancy.oauth.server;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.oauth.provider.ConsumerDetails;
import org.springframework.security.oauth.provider.ConsumerDetailsService;
import org.springframework.security.oauth.provider.token.OAuthProviderToken;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenServices;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class ConfirmationController extends AbstractController {
private OAuthProviderTokenServices tokenServices;
private ConsumerDetailsService consumerDetailsService;
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
String token = request.getParameter("oauth_token");
if (token == null) {
throw new IllegalArgumentException("A request token to authorize must be provided.");
}
OAuthProviderToken providerToken = getTokenServices().getToken(token);
ConsumerDetails consumer = getConsumerDetailsService().loadConsumerByConsumerKey(providerToken.getConsumerKey());
String callback = request.getParameter("oauth_callback");
TreeMap<String, Object> model = new TreeMap<String, Object>();
model.put("oauth_token", token);
if (callback != null) {
model.put("oauth_callback", callback);
}
model.put("consumer", consumer);
return new ModelAndView("access_confirmation", model);
}
public OAuthProviderTokenServices getTokenServices() {
return tokenServices;
}
public void setTokenServices(OAuthProviderTokenServices tokenServices) {
this.tokenServices = tokenServices;
}
public ConsumerDetailsService getConsumerDetailsService() {
return consumerDetailsService;
}
public void setConsumerDetailsService(ConsumerDetailsService consumerDetailsService) {
this.consumerDetailsService = consumerDetailsService;
}
}


SecurityController:

package com.coolfancy.oauth.server;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class SecurityController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType("html/plain");
final PrintWriter out = response.getWriter();
out.println("Hello World!");
out.close();
return null;
}
}



下面是客户端,首先是web.xml:

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/security/*</url-pattern>
</servlet-mapping>


Spring MVC配置(/WEB-INF/spring-servlet.xml):

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean name="/test" class="com.coolfancy.oauth.client.SecurityController">
<property name="security_url" value="http://localhost:8080/server/security" />
<property name="support" ref="oauthConsumerSupport" />
</bean>



Spring Security配置(/WEB-INF/applicationContext.xml):

<http auto-config="true">
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
</http>
<authentication-provider>
<user-service>
<user name="a" password="a" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
<oauth:consumer resource-details-service-ref="resourceDetails">
<oauth:url pattern="/security/**" resources="security_content" />
</oauth:consumer>
<oauth:resource-details-service id="resourceDetails">
<oauth:resource id="security_content" key="fancy-consumer-key" secret="SHHHHH!!!!!!!!!!" request-token-url="http://localhost:8080/server/oauth/request_token"
user-authorization-url="http://localhost:8080/server/oauth/confirm_access" access-token-url="http://localhost:8080/server/oauth/access_token" />
</oauth:resource-details-service>


最后是SecurityController:

package com.coolfancy.oauth.client;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.oauth.consumer.CoreOAuthConsumerSupport;
import org.springframework.security.oauth.consumer.OAuthConsumerProcessingFilter;
import org.springframework.security.oauth.consumer.token.OAuthConsumerToken;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class SecurityController extends AbstractController {
private String security_url;
private CoreOAuthConsumerSupport support;
@SuppressWarnings("unchecked")
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
OAuthConsumerToken token = null;
final List<OAuthConsumerToken> tokens = (List<OAuthConsumerToken>) request.getAttribute(OAuthConsumerProcessingFilter.ACCESS_TOKENS_DEFAULT_ATTRIBUTE);
if (tokens != null) {
for (OAuthConsumerToken consumerToken : tokens) {
if (consumerToken.getResourceId().equals("security_content")) {
token = consumerToken;
break;
}
}
}
if (token == null) {
throw new IllegalArgumentException("Access token not found.");
}
final InputStream stream = support.readProtectedResource(new URL(security_url), token, "GET");
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
final String content = reader.readLine();
reader.close();
return new ModelAndView("security", "content", content);
}
public CoreOAuthConsumerSupport getSupport() {
return support;
}
public void setSupport(CoreOAuthConsumerSupport support) {
this.support = support;
}
public String getSecurity_url() {
return security_url;
}
public void setSecurity_url(String security_url) {
this.security_url = security_url;
}
}


运行效果如下。

访问客户程序首页,点击连接后客户程序请求访问第三方资源:


第三方进行用户认证:




认证后完成后,第三方要求用户确认被授权访问的资源:




授权访问完成,客户程序显示被授权访问的资源内容:




完整的样例工程下载:spring_security_oauth_helloworld.zip
  • 大小: 50 KB
  • 大小: 67.8 KB
  • 大小: 91 KB
  • 大小: 68.6 KB
分享到:
评论
2 楼 小清新雪仔_ 2017-03-12  
报错The import org.springframework.security.oauth cannot be
resolved
为什么??缺少了什么jar包吗??
1 楼 xiaoxiao_qiang 2015-07-04  
感谢,正在学习oAuth,有机会一起交流

相关推荐

Global site tag (gtag.js) - Google Analytics