package io.loli.sc.server.oauth2; import io.loli.sc.server.entity.User; import io.loli.sc.server.entity.oauth2.AccessToken; import io.loli.sc.server.entity.oauth2.Application; import io.loli.sc.server.service.UserService; import io.loli.sc.server.service.oauth2.AppService; import io.loli.sc.server.service.oauth2.TokenService; import java.io.IOException; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang3.StringUtils; import org.apache.oltu.oauth2.as.issuer.MD5Generator; import org.apache.oltu.oauth2.as.issuer.OAuthIssuer; import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl; import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest; import org.apache.oltu.oauth2.as.request.OAuthTokenRequest; import org.apache.oltu.oauth2.as.response.OAuthASResponse; import org.apache.oltu.oauth2.common.exception.OAuthProblemException; import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.apache.oltu.oauth2.common.message.OAuthResponse; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Named @RequestMapping(value = "oauth2") @Singleton public class AuthServer { private OAuthIssuerImpl oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator()); @Inject private AppService appService; @Inject private TokenService tokenService; @Inject private UserService userService; // WeakMap 会自动进行垃圾回收 private Map<String, User> codeMap = Collections.synchronizedMap(new WeakHashMap<String, User>()); @RequestMapping(value = "auth", method = RequestMethod.GET) @ResponseBody public String executeGet(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws OAuthSystemException, IOException { OAuthResponse resp = null; try { // dynamically recognize an OAuth profile based on request // characteristic (params, // method, content type etc.), perform validation OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request); if (appService.checkExist(oauthRequest.getClientId())) { String username = request.getParameter("username"); String passwd = request.getParameter("password"); if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(passwd)) { User user = null; if ((user = userService.findByEmail(username)) != null && user.getPassword().equals(passwd)) { String code = oauthIssuerImpl.authorizationCode(); // build OAuth response resp = OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND) .setCode(code).location(oauthRequest.getRedirectURI()).buildJSONMessage(); codeMap.put(code, user); } else { throw OAuthProblemException.error("username or password is incorrect"); } } else { throw OAuthProblemException.error("username or password is blank"); } } else { throw OAuthProblemException.error("App key is invalid"); } } catch (OAuthProblemException ex) { resp = OAuthASResponse.errorResponse(HttpServletResponse.SC_FOUND).error(ex).buildJSONMessage(); } return resp.getBody(); } @RequestMapping(value = "code", method = RequestMethod.POST) @ResponseBody public String executePost(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws OAuthSystemException, IOException { OAuthTokenRequest oauthRequest = null; OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator()); OAuthResponse r = null; try { oauthRequest = new OAuthTokenRequest(request); // validateClient(oauthRequest); String authzCode = oauthRequest.getCode(); // validate code if (codeMap.containsKey(authzCode)) { // validate id and secret if (appService.verify(oauthRequest)) { // some code String accessToken = oauthIssuerImpl.accessToken(); // some code r = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK).setAccessToken(accessToken) .buildJSONMessage(); Application app = appService.findByKey(oauthRequest.getClientId()); AccessToken token = new AccessToken(); token.setApp(app); token.setToken(accessToken); token.setExpired(Long.MAX_VALUE); token.setUser((User) session.getAttribute("user")); tokenService.save(token); codeMap.remove(authzCode); } else { throw OAuthProblemException.error("app_key or app_secret is incorrect"); } } else { throw OAuthProblemException.error("code does not exist"); } // if something goes wrong } catch (OAuthProblemException ex) { r = OAuthResponse.errorResponse(401).error(ex).buildJSONMessage(); } return r.getBody(); } }