1 importjava.util.List;2
3 importjavax.servlet.http.HttpServletRequest;4 importjavax.servlet.http.HttpServletResponse;5
6 importorg.openid4java.OpenIDException;7 importorg.openid4java.consumer.ConsumerManager;8 importorg.openid4java.consumer.VerificationResult;9 importorg.openid4java.discovery.DiscoveryInformation;10 importorg.openid4java.discovery.Identifier;11 importorg.openid4java.message.AuthRequest;12 importorg.openid4java.message.AuthSuccess;13 importorg.openid4java.message.ParameterList;14 importorg.openid4java.message.ax.AxMessage;15 importorg.openid4java.message.ax.FetchRequest;16 importorg.openid4java.message.ax.FetchResponse;17 importorg.slf4j.Logger;18 importorg.slf4j.LoggerFactory;19 importorg.springframework.stereotype.Controller;20 importorg.springframework.web.bind.annotation.RequestMapping;21 importorg.springframework.web.util.UriComponentsBuilder;22
23 importcom.google.common.base.Throwables;24
25 @Controller26 @RequestMapping("/openid")27 @SuppressWarnings("rawtypes")28 public classSecurityOpenIDController {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 = newConsumerManager();34
35 @RequestMapping("/login")36 public voidlogin(37 UriComponentsBuilder builder,38 HttpServletRequest request,39 HttpServletResponse response40 ) throwsException41 {42 //configure the return_to URL where your application will receive43 //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 provider56 //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 endpoint76 //The only method supported in OpenID 1.x77 //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 voidverifyResponse(HttpServletRequest request) {87 String email = null;88 String lastName = null;89 String firstName = null;90
91 try{92 //extract the parameters from the authentication response93 //(which comes in as a HTTP request from the OpenID provider)
94 ParameterList response = newParameterList(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 same107 //(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 verified111 //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 //success133
134 //在这里与安全框架集成 apache-shiro/spring-security135 //这里要根据相关的信息自己定义Principal
136 }137 } catch(OpenIDException e) {138 LOGGER.error(e.getMessage(), e);139 Throwables.propagate(e);140 }141 }142 }