以GoogleOpenID 为例,试验了OAuth单点登录的用法:
1 <dependency>
2 <groupId>org.openid4java</groupId>
3 <artifactId>openid4java</artifactId>
4 <version>0.9.8</version>
5 </dependency>
1 import java.util.List;
2
3 import javax.servlet.http.HttpServletRequest;
4 import javax.servlet.http.HttpServletResponse;
5
6 import org.openid4java.OpenIDException;
7 import org.openid4java.consumer.ConsumerManager;
8 import org.openid4java.consumer.VerificationResult;
9 import org.openid4java.discovery.DiscoveryInformation;
10 import org.openid4java.discovery.Identifier;
11 import org.openid4java.message.AuthRequest;
12 import org.openid4java.message.AuthSuccess;
13 import org.openid4java.message.ParameterList;
14 import org.openid4java.message.ax.AxMessage;
15 import org.openid4java.message.ax.FetchRequest;
16 import org.openid4java.message.ax.FetchResponse;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19 import org.springframework.stereotype.Controller;
20 import org.springframework.web.bind.annotation.RequestMapping;
21 import org.springframework.web.util.UriComponentsBuilder;
22
23 import com.google.common.base.Throwables;
24
25 @Controller
26 @RequestMapping("/openid")
27 @SuppressWarnings("rawtypes")
28 public class SecurityOpenIDController {
29
30 public static final String GOOGLE_ENDPOINT = "https://www.google.com/accounts/o8/id";
31 private static final Logger LOGGER = LoggerFactory.getLogger(SecurityOpenIDController.class);
32
33 public final ConsumerManager manager = new ConsumerManager();
34
35 @RequestMapping("/login")
36 public void login(
37 UriComponentsBuilder builder,
38 HttpServletRequest request,
39 HttpServletResponse response
40 ) throws Exception
41 {
42 // configure the return_to URL where your application will receive
43 // the authentication responses from the OpenID provider
44 String returnUrl = builder.path("/openid/return").build().toUriString();
45
46 // --- Forward proxy setup (only if needed) ---
47 // ProxyProperties proxyProps = new ProxyProperties();
48 // proxyProps.setProxyName("proxy.example.com");
49 // proxyProps.setProxyPort(8080);
50 // HttpClientFactory.setProxyProperties(proxyProps);
51
52 // perform discovery on the user-supplied identifier
53 List discoveries = manager.discover(GOOGLE_ENDPOINT);
54
55 // attempt to associate with the OpenID provider
56 // and retrieve one service endpoint for authentication
57 DiscoveryInformation discovered = manager.associate(discoveries);
58
59 // store the discovery information in the user's session
60 request.getSession().setAttribute("openid-disc", discovered);
61
62 // obtain a AuthRequest message to be sent to the OpenID provider
63 AuthRequest authReq = manager.authenticate(discovered, returnUrl);
64
65 // attribute Exchange
66 FetchRequest fetch = FetchRequest.createFetchRequest();
67 fetch.addAttribute("email", "http://axschema.org/contact/email", true);
68 fetch.addAttribute("firstName", "http://axschema.org/namePerson/first", true);
69 fetch.addAttribute("lastName", "http://axschema.org/namePerson/last", true);
70
71 // attach the extension to the authentication request
72 authReq.addExtension(fetch);
73
74 if (!discovered.isVersion2()) {
75 // Option 1: GET HTTP-redirect to the OpenID Provider endpoint
76 // The only method supported in OpenID 1.x
77 // redirect-URL usually limited ~2048 bytes
78 response.sendRedirect(authReq.getDestinationUrl(true));
79 } else {
80 // Option 2: HTML FORM Redirection (Allows payloads >2048 bytes)
81 response.sendRedirect(authReq.getDestinationUrl(true));
82 }
83 }
84
85 @RequestMapping("/return")
86 public void verifyResponse(HttpServletRequest request) {
87 String email = null;
88 String lastName = null;
89 String firstName = null;
90
91 try {
92 // extract the parameters from the authentication response
93 // (which comes in as a HTTP request from the OpenID provider)
94 ParameterList response = new ParameterList(request.getParameterMap());
95
96 // retrieve the previously stored discovery information
97 DiscoveryInformation discovered = (DiscoveryInformation) request.getSession().getAttribute("openid-disc");
98
99 // extract the receiving URL from the HTTP request
100 StringBuffer receivingURL = request.getRequestURL();
101 String queryString = request.getQueryString();
102 if (queryString != null && queryString.length() > 0) {
103 receivingURL.append("?").append(request.getQueryString());
104 }
105
106 // verify the response; ConsumerManager needs to be the same
107 // (static) instance used to place the authentication request
108 VerificationResult verification = manager.verify(receivingURL.toString(), response, discovered);
109
110 // examine the verification result and extract the verified
111 // identifier
112 Identifier verified = verification.getVerifiedId();
113 if (verified != null) {
114 AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
115
116 if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
117 FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);
118
119 List emails = fetchResp.getAttributeValues("email");
120 email = (String) emails.get(0);
121
122 List lastNames = fetchResp.getAttributeValues("lastName");
123 lastName = (String) lastNames.get(0);
124
125 List firstNames = fetchResp.getAttributeValues("firstName");
126 firstName = (String) firstNames.get(0);
127
128 LOGGER.debug("email: {}", email);
129 LOGGER.debug("lastName: {}", lastName);
130 LOGGER.debug("firstName: {}", firstName);
131 }
132 // success
133
134 // 在这里与安全框架集成 apache-shiro/spring-security
135 // 这里要根据相关的信息自己定义Principal
136 }
137 } catch (OpenIDException e) {
138 LOGGER.error(e.getMessage(), e);
139 Throwables.propagate(e);
140 }
141 }
142