当前位置: 首页 > 工具软件 > OpenID4Java > 使用案例 >

SpringMVC杂记(十六) spring-mvc 与 openid4java

徐兴昌
2023-12-01
SpringMVC杂记(十六) spring-mvc 与 openid4java
以GoogleOpenID 为例,试验了OAuth单点登录的用法


<dependency>
<groupId>org.openid4java</groupId>
<artifactId>openid4java</artifactId>
<version>0.9.8</version>
</dependency>



import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.openid4java.OpenIDException;
import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.VerificationResult;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.discovery.Identifier;
import org.openid4java.message.AuthRequest;
import org.openid4java.message.AuthSuccess;
import org.openid4java.message.ParameterList;
import org.openid4java.message.ax.AxMessage;
import org.openid4java.message.ax.FetchRequest;
import org.openid4java.message.ax.FetchResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.util.UriComponentsBuilder;

import com.google.common.base.Throwables;

@Controller
@RequestMapping("/openid")
@SuppressWarnings("rawtypes")
public class SecurityOpenIDController {

public static final String GOOGLE_ENDPOINT = "https://www.google.com/accounts/o8/id";
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityOpenIDController.class);

public final ConsumerManager manager = new ConsumerManager();

@RequestMapping("/login")
public void login(
UriComponentsBuilder builder,
HttpServletRequest request,
HttpServletResponse response
) throws Exception
{
// configure the return_to URL where your application will receive
// the authentication responses from the OpenID provider
String returnUrl = builder.path("/openid/return").build().toUriString();

// --- Forward proxy setup (only if needed) ---
// ProxyProperties proxyProps = new ProxyProperties();
// proxyProps.setProxyName("proxy.example.com");
// proxyProps.setProxyPort(8080);
// HttpClientFactory.setProxyProperties(proxyProps);

// perform discovery on the user-supplied identifier
List discoveries = manager.discover(GOOGLE_ENDPOINT);

// attempt to associate with the OpenID provider
// and retrieve one service endpoint for authentication
DiscoveryInformation discovered = manager.associate(discoveries);

// store the discovery information in the user's session
request.getSession().setAttribute("openid-disc", discovered);

// obtain a AuthRequest message to be sent to the OpenID provider
AuthRequest authReq = manager.authenticate(discovered, returnUrl);

// attribute Exchange
FetchRequest fetch = FetchRequest.createFetchRequest();
fetch.addAttribute("email", "http://axschema.org/contact/email", true);
fetch.addAttribute("firstName", "http://axschema.org/namePerson/first", true);
fetch.addAttribute("lastName", "http://axschema.org/namePerson/last", true);

// attach the extension to the authentication request
authReq.addExtension(fetch);

if (!discovered.isVersion2()) {
// Option 1: GET HTTP-redirect to the OpenID Provider endpoint
// The only method supported in OpenID 1.x
// redirect-URL usually limited ~2048 bytes
response.sendRedirect(authReq.getDestinationUrl(true));
} else {
// Option 2: HTML FORM Redirection (Allows payloads >2048 bytes)
response.sendRedirect(authReq.getDestinationUrl(true));
}
}

@RequestMapping("/return")
public void verifyResponse(HttpServletRequest request) {
String email = null;
String lastName = null;
String firstName = null;

try {
// extract the parameters from the authentication response
// (which comes in as a HTTP request from the OpenID provider)
ParameterList response = new ParameterList(request.getParameterMap());

// retrieve the previously stored discovery information
DiscoveryInformation discovered = (DiscoveryInformation) request.getSession().getAttribute("openid-disc");

// extract the receiving URL from the HTTP request
StringBuffer receivingURL = request.getRequestURL();
String queryString = request.getQueryString();
if (queryString != null && queryString.length() > 0) {
receivingURL.append("?").append(request.getQueryString());
}

// verify the response; ConsumerManager needs to be the same
// (static) instance used to place the authentication request
VerificationResult verification = manager.verify(receivingURL.toString(), response, discovered);

// examine the verification result and extract the verified
// identifier
Identifier verified = verification.getVerifiedId();
if (verified != null) {
AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();

if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);

List emails = fetchResp.getAttributeValues("email");
email = (String) emails.get(0);

List lastNames = fetchResp.getAttributeValues("lastName");
lastName = (String) lastNames.get(0);

List firstNames = fetchResp.getAttributeValues("firstName");
firstName = (String) firstNames.get(0);

LOGGER.debug("email: {}", email);
LOGGER.debug("lastName: {}", lastName);
LOGGER.debug("firstName: {}", firstName);
}
// success

// 在这里与安全框架集成 apache-shiro/spring-security
// 这里要根据相关的信息自己定义Principal
}
} catch (OpenIDException e) {
LOGGER.error(e.getMessage(), e);
Throwables.propagate(e);
}
}
}
 类似资料: