• Java Shiro apache olut 实现SSO


    公司项目需求,需要做SSO统一认证,开发完毕后,把相关思路整理下。

    涉及相关OAuth2基础知识:

    https://www.cnblogs.com/kaleidoscope/p/9507261.html

    先上流程图:

    主要流程:

    1.client 去认证中心获取 Auth Code

    2.Client 根据 Auth Code 去资源服务器获取 Token(项目认证中心和资源服务器都统一在一个APP了)

    3.Client 向认证中心请求跳转到Client 端

    4.认证中心验证 Token,并向目标Client 端发送写session 的请求

    5.目标Client 收到写入Session请求后,向 资源服务器验证Token,写入session,然后跳转到具体页面

     

    大概流程写完了,现在上代码。

    一、认证中心代码:

    LoginController.java

    package demo.sso.controller;
    
    import java.util.ArrayList;
    import java.util.List;
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.LockedAccountException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.session.Session;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;
    import demo.sso.ResponseCodes;
    import demo.sso.entity.Client;
    import demo.sso.entity.User;
    import demo.sso.helpers.HttpRequestHelper;
    import demo.sso.helpers.ShiroSecurityHelper;
    import demo.sso.helpers.VerifyCodeHelper;
    import demo.sso.model.ChangePasswordModel;
    import demo.sso.model.JsonResult;
    import demo.sso.model.LoginModel;
    import demo.sso.server.ClientService;
    import demo.sso.server.OAuthService;
    import demo.sso.server.UserService;
    import demo.sso.shiro.token.PhoneCodeToken;
    import demo.sso.utils.ExceptionUtils;
    
    @Controller
    public class LoginController {
    	
    	@Autowired
    	private HttpRequestHelper httpRequestHelper;
    	
    	@Autowired
    	private ClientService clientService;
    	
    	@Autowired
    	private OAuthService oAuthService;
    	
    	@Autowired
    	private UserService userService;
    	
    	@Autowired
    	private ShiroSecurityHelper shiroSecurityHelper;
    	
    	@Autowired
    	private VerifyCodeHelper verifyCodeHelper;
    	
    	private static final Logger logger = LoggerFactory.getLogger(LoginController.class);
    	
    	private List<Client> getClients()
    	{
    		List<Client> clients = clientService.findAll();
    		List<Client> clientList = new ArrayList<Client>();;
    		for(Client client :clients)
    		{
    			if(client.canUsed())
    				clientList.add(client);
    		}
    		return clientList;
    	}
    	
    	@RequestMapping(value = { "/", "/index" }, method = RequestMethod.GET)
    	public Object index(HttpServletRequest request,ModelMap model)
    	{
    		model.addAttribute("name",shiroSecurityHelper.getName());
    		model.addAttribute("clients", getClients());
    		return "index";
    	}
    	@RequestMapping(value = { "/changePassword" }, method = RequestMethod.GET)
    	public String changePassword()
    	{
    		return "changePassword";
    	}
    	@RequestMapping(value = { "/changePassword" }, method = RequestMethod.POST)
    	public Object changePassword(@ModelAttribute("SpringWeb")ChangePasswordModel data 
    			,ModelMap model
    			,HttpServletRequest request) {
    		
    		if(!data.getNewPassword().equals(data.getConfirmPassword()))
    		{
    			ModelAndView mav=new ModelAndView("changePassword");
    			mav.addObject("error", "密码不一致。");
    			return mav;
    		}
    		if(!userService.changePassword(shiroSecurityHelper.getUserid(), data.getOldPassword(),data.getNewPassword()))
    		{
    			ModelAndView mav=new ModelAndView("changePassword");
    			mav.addObject("error", "密码修改失败!");
    			return mav;
    		}
    		else
    		{
    			return "redirect:/logout";
    		}
    	}
    	
    	@RequestMapping(value = { "/login" }, method = RequestMethod.GET)
    	public Object login(HttpServletRequest req){
    		if(shiroSecurityHelper.isAuthenticated())
    		{
    			return "redirect:/";
    		}
    		if(shiroSecurityHelper.isAuthenticated())
    		{
    	        ModelAndView mav=new ModelAndView("login");
    	        mav.addObject("error", "您登录,请勿重复登录");
    			return mav;
    		}
    		
    		String error=null;
    		String exceptionClassName = (String)req.getAttribute("shiroLoginFailure");
            if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
                error = "账号不正确!";
            } else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
                error = "密码不正确!";
            } else if(LockedAccountException.class.getName().equals(exceptionClassName)) {
                error = "账号被锁定!";
            } else if(AuthenticationException.class.getName().equals(exceptionClassName)) {
                error = "登录失败!!";
            } else if(exceptionClassName != null) {
                error = "登录失败:" + exceptionClassName;
            }
            logger.debug(exceptionClassName);
            ModelAndView mav=new ModelAndView("login");
            mav.addObject("error", error);
    		return mav;
    	}
    	
    	@RequestMapping(value = { "/login" }, method = RequestMethod.POST)
    	public Object login(@ModelAttribute("SpringWeb")LoginModel login 
    			,BindingResult result
    			,ModelMap model
    			,HttpServletRequest request) {
    		if(shiroSecurityHelper.isAuthenticated())
    		{
    			return "redirect:/index";
    		}
    		String error=null;
    		try
    		{
    			Session session = shiroSecurityHelper.getSession();
    			
    			if("phone".equals(login.getType()))
    			{
    				PhoneCodeToken token = new PhoneCodeToken(login.getUsername(),login.getPassword());
    				shiroSecurityHelper.login(token);
    			}
    			else
    			{
    				UsernamePasswordToken token=new UsernamePasswordToken(login.getUsername(),login.getPassword());
    				shiroSecurityHelper.login(token);
    			}
    			User user = userService.findByPhone(login.getUsername());
    			List navigationBar=userService.getNavigationBar(user.getUsername());
    			session.setAttribute("navibar", navigationBar);
    			session.setAttribute("username", user.getUsername());
    			session.setAttribute("name", user.getName());
    			session.setAttribute("userid", user.getUserid());
    			session.setAttribute("email", user.getEmail());
    			session.setAttribute("phone", user.getPhone());
    		}
    		catch(Exception e)
    		{	
    			e.printStackTrace();
    			String exceptionClassName = e.getClass().getName();
    	        if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
    		          error = "账号不正确!";
    		    } else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
    		          error = "密码不正确!";
    		    } else if(LockedAccountException.class.getName().equals(exceptionClassName)) {
    		          error = "账号被锁定!";
    		    } else if(AuthenticationException.class.getName().equals(exceptionClassName)) {
    		          error = "登录失败!";
    		    } else if(exceptionClassName != null) {
    		          error = "登录失败:" + exceptionClassName;
    		    }
    		    else
    		    {
    		    	error = "登录失败!!";
    		    }
    	        ModelAndView mav=new ModelAndView("login");
    	        mav.addObject("error", error);
    			return mav;
    		}
    		return "redirect:"+getReturnUrl(request,login);
    	}
    	@RequestMapping("/logout")
    	public Object logout(HttpServletRequest request)
    	{
    		String accessToken = shiroSecurityHelper.getSessionAccessToken();
    		
    		shiroSecurityHelper.logout();
    		
    		if(accessToken!=null&& accessToken.length()>0)
            {
            	String username =oAuthService.getUsernameByAccessToken(accessToken.toString());
            	oAuthService.removeAccessToken(accessToken.toString());
            	
            	shiroSecurityHelper.kickOutUser(username);
            }
            System.out.println( "no token redirect:" +httpRequestHelper.getCobineUrl(request, "/login"));
            return "redirect:"+httpRequestHelper.getCobineUrl(request, "/login");
    	}
    	
    	@RequestMapping("/checkCode")
    	public Object checkCode(HttpServletRequest req,String phone){
    		JsonResult result = new JsonResult();
    		try
    		{
    			String code = verifyCodeHelper.createVerifyCode(6);
    			System.out.println(code);
    			boolean flag = userService.updateCode(phone, code);
    			if(!flag)
    			{
    				result.setCode(ResponseCodes.SMS_SEND_FIAL);
    			}
    		}catch(Exception e)
    		{
    			logger.error(ExceptionUtils.getMessage(e));
    			e.printStackTrace();
    			result.setCode(ResponseCodes.SYSTEM_ERROR);
    		}
    		return new ResponseEntity(result.toString(), HttpStatus.OK);
    	}
    	
    	private String getReturnUrl(HttpServletRequest request,LoginModel login)
    	{
    		String returnUrl = login.getReturnUrl();
    		if(returnUrl!=null)
    			return returnUrl;
    		else
    			return httpRequestHelper.getCobineUrl(request, "/");
    	}
    }
    

      OAuth2Controller.java

    package demo.sso.controller;
    
    import java.net.URI;
    import java.net.URISyntaxException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    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.OAuth;
    import org.apache.oltu.oauth2.common.error.OAuthError;
    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.apache.oltu.oauth2.common.message.types.GrantType;
    import org.apache.oltu.oauth2.common.message.types.ResponseType;
    import org.apache.oltu.oauth2.common.utils.OAuthUtils;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpEntity;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import com.alibaba.fastjson.JSON;
    import demo.sso.server.ClientService;
    import demo.sso.server.OAuthService;
    import demo.sso.utils.ExceptionUtils;
    import demo.sso.ResponseCodes;
    import demo.sso.ResponseMessages;
    import demo.sso.entity.Client;
    import demo.sso.entity.Status;
    import demo.sso.helpers.HttpRequestHelper;
    import demo.sso.helpers.ShiroSecurityHelper;
    import demo.sso.mapper.ClientMapper;
    import demo.sso.model.JsonResult;
    
    @Controller
    @RequestMapping("/v1/oauth2")
    public class OAuth2Controller {
    	@Autowired
    	private ClientMapper clientMapper;
    	@Autowired
    	private HttpRequestHelper httpRequestHelper;
        @Autowired
        private OAuthService oAuthService;
        @Autowired
        private ClientService clientService;
        @Autowired
    	private ShiroSecurityHelper shiroSecurityHelper;
        
    	private static final Logger logger = LoggerFactory.getLogger(OAuth2Controller.class);
        /**
         * 服务端授权页面,获取授权 code
         * @param model
         * @param request
         * @return
         * @throws URISyntaxException
         * @throws OAuthSystemException
         */
        @SuppressWarnings("unchecked")
    	@RequestMapping(value = "/authorize")
        public Object authorize(
                Model model,
                HttpServletRequest request)
                throws URISyntaxException, OAuthSystemException {
        	logger.debug("---------服务端端/authorize----------------------------------------------------------------------------------");
    		
            try {
    
                HttpHeaders headers = new HttpHeaders();
                headers.set("Content-Type","application/json; charset=utf-8");
    
                //构建OAuth 授权请求
                OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request);
    
                //检查传入的客户端id是否正确
                if (!oAuthService.checkClientId(oauthRequest.getClientId())) {
                    OAuthResponse response =
                            OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                                    .setError(OAuthError.TokenResponse.INVALID_CLIENT)
                                    .setErrorDescription(ResponseMessages.getMessage(ResponseCodes.INVALID_CLIENT_ID))
                                    .buildJSONMessage();
                    return new ResponseEntity(response.getBody(), headers, HttpStatus.valueOf(response.getResponseStatus()));
                }
    
                //如果用户没有登录,跳转到登陆页面
                if (!login(request)) {//登录失败时跳转到登陆页面
                	model.addAttribute("client", clientService.findByClientId(oauthRequest.getClientId()));
                    return "oauth2login";
                }
    
                String username="";
                if ("get".equalsIgnoreCase(request.getMethod())) {
                	
                	username = shiroSecurityHelper.getUsername();
                }
                else
    			{
    			    username = request.getParameter("username"); //获取用户名
    			}
                
                //生成授权码
                String authorizationCode = null;
                //responseType目前仅支持CODE,另外还有TOKEN
                String responseType = oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE);
                if (responseType.equals(ResponseType.CODE.toString())) {
                    OAuthIssuerImpl oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
                    authorizationCode = oauthIssuerImpl.authorizationCode();
                    oAuthService.addAuthCode(authorizationCode, username);
                }
    
                //进行OAuth响应构建
                OAuthASResponse.OAuthAuthorizationResponseBuilder builder =
                        OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND);
                //设置授权码
                builder.setCode(authorizationCode);
                logger.debug("authorizationCode="+authorizationCode);
                
                //得到到客户端重定向地址
                String redirectURI = oauthRequest.getParam(OAuth.OAUTH_REDIRECT_URI);
    
                //构建响应
                final OAuthResponse response = builder.location(redirectURI).buildQueryMessage();
    
                //根据OAuthResponse返回ResponseEntity响应
                headers = new HttpHeaders();
                headers.set("Content-Type","application/json; charset=utf-8");
                headers.setLocation(new URI(response.getLocationUri()));
                return new ResponseEntity(headers, HttpStatus.valueOf(response.getResponseStatus()));
            } catch (OAuthProblemException e) {
            	logger.error(ExceptionUtils.getMessage(e));
            	e.printStackTrace();
                //出错处理
                String redirectUri = e.getRedirectUri();
                if (OAuthUtils.isEmpty(redirectUri)) {
                    //告诉客户端没有传入redirectUri直接报错
                    HttpHeaders headers = new HttpHeaders();
                    headers.add("Content-Type", "application/json; charset=utf-8");
                    Status status = new Status();
                    status.setCode(HttpStatus.NOT_FOUND.value());
                    status.setMsg(ResponseMessages.getMessage(ResponseCodes.INVALID_REDIRECT_URI));
                    return new ResponseEntity(JSON.toJSONString(status), headers, HttpStatus.NOT_FOUND);
                }
                //返回错误消息(如?error=)
                final OAuthResponse response =
                        OAuthASResponse.errorResponse(HttpServletResponse.SC_FOUND)
                                .error(e).location(redirectUri).buildQueryMessage();
                HttpHeaders headers = new HttpHeaders();
                headers.setLocation(new URI(response.getLocationUri()));
                return new ResponseEntity(headers, HttpStatus.valueOf(response.getResponseStatus()));
            }
        }
    
        /**
         * 服务端授权页面-登录验证
         * @param request
         * @return
         */
        private boolean login(HttpServletRequest request) {		
        	if ("get".equalsIgnoreCase(request.getMethod())) {
            	if(!shiroSecurityHelper.isAuthenticated())
            	{
                    request.setAttribute("error", "请先登录");
                    return false;
            	}    		
            	else
            	{
            		return true;
            	}
            }      
        	
        	String username = request.getParameter("username");
            String password = request.getParameter("password");
    
            if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
                  request.setAttribute("error", "登录失败:用户名或密码不能为空");
                  return false;
            }
        	
        	//用户名和密码都保存在model中
            //基于shiro实现登录
            //用户名和密码保存到token中
            AuthenticationToken token= new UsernamePasswordToken(username,password);
            try {
                //如果正常登录,表示没有异常.登陆成功
            	shiroSecurityHelper.login(token);
                return true;
            } catch (Exception e) {
            	logger.error(ExceptionUtils.getMessage(e));
                //如果异常,表示登录失败,重新跳转到登录页面
                e.printStackTrace();
                request.setAttribute("error", "登录失败,服务器繁忙.");
                return false;
            }
        }
    
        /**
         * 根据code 获取 accessToken
         * @param request
         * @return
         * @throws URISyntaxException
         * @throws OAuthSystemException
         */
        @RequestMapping("/accessToken")
        public HttpEntity token(HttpServletRequest request)
                throws URISyntaxException, OAuthSystemException {
        	logger.debug("---------服务端端/accessToken----------------------------------------------------------------------------------");
    		
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type","application/json; charset=utf-8");
    
            try {
    
                //构建OAuth请求
                OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request);
    
                //检查提交的客户端id是否正确
                if (!oAuthService.checkClientId(oauthRequest.getClientId())) {
                    OAuthResponse response =
                            OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                                    .setError(OAuthError.TokenResponse.INVALID_CLIENT)
                                    .setErrorDescription(ResponseMessages.getMessage(ResponseCodes.INVALID_CLIENT_ID))
                                    .buildJSONMessage();
                    return new ResponseEntity(response.getBody(), headers, HttpStatus.valueOf(response.getResponseStatus()));
                }
    
                // 检查客户端安全KEY是否正确
                if (!oAuthService.checkClientSecret(oauthRequest.getClientSecret())) {
                    OAuthResponse response =
                            OAuthASResponse.errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
                                    .setError(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)
                                    .setErrorDescription(ResponseMessages.getMessage(ResponseCodes.INVALID_CLIENT_ID))
                                    .buildJSONMessage();
                    return new ResponseEntity(response.getBody(), headers, HttpStatus.valueOf(response.getResponseStatus()));
                }
    
                String authCode = oauthRequest.getParam(OAuth.OAUTH_CODE);
                // 检查验证类型,此处只检查AUTHORIZATION_CODE类型,其他的还有PASSWORD或REFRESH_TOKEN
                if (oauthRequest.getParam(OAuth.OAUTH_GRANT_TYPE).equals(GrantType.AUTHORIZATION_CODE.toString())) {
                    if (!oAuthService.checkAuthCode(authCode)) {
                        OAuthResponse response = OAuthASResponse
                                .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                                .setError(OAuthError.TokenResponse.INVALID_GRANT)
                                .setErrorDescription(ResponseMessages.getMessage(ResponseCodes.INVALID_AUTH_CODE))
                                .buildJSONMessage();
                        return new ResponseEntity(response.getBody(), headers, HttpStatus.valueOf(response.getResponseStatus()));
                    }
                }
    
                //生成Access Token
                OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
                final String accessToken = oauthIssuerImpl.accessToken();
                oAuthService.addAccessToken(accessToken, oAuthService.getUsernameByAuthCode(authCode));
    
                //生成OAuth响应
                OAuthResponse response = OAuthASResponse
                        .tokenResponse(HttpServletResponse.SC_OK)
                        .setAccessToken(accessToken)
                        .setExpiresIn(String.valueOf(oAuthService.getExpireIn()))
                        .buildJSONMessage();
    
                oAuthService.removeAuthCode(authCode);
                
                //将最后的session信息写入到 session 中
                shiroSecurityHelper.setSessionAccessToken(accessToken);
                logger.debug("accessToken="+accessToken);
                
                //根据OAuthResponse生成ResponseEntity
                return new ResponseEntity(response.getBody(), headers, HttpStatus.valueOf(response.getResponseStatus()));
            } catch (OAuthProblemException e) {
            	logger.error(ExceptionUtils.getMessage(e));
                //构建错误响应
                OAuthResponse res = OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST).error(e)
                        .buildJSONMessage();
                return new ResponseEntity(res.getBody(), headers, HttpStatus.valueOf(res.getResponseStatus()));
            }
        }
    
        /**
         * 验证accessToken
         *
         * @param accessToken
         * @return
         */
        @RequestMapping(value = "/checkAccessToken", method = RequestMethod.POST)
        public ResponseEntity checkAccessToken(@RequestParam("accessToken") String accessToken) {
        	logger.debug("---------服务端端/checkAccessToken----------------------------------------------------------------------------------");
    		
        	boolean b = oAuthService.checkAccessToken(accessToken);
            return b ? new ResponseEntity(HttpStatus.valueOf(HttpServletResponse.SC_OK)) : new ResponseEntity(HttpStatus.valueOf(HttpServletResponse.SC_UNAUTHORIZED));
        }
        
        @RequestMapping(value = "/serverRedirect")
        public String serverRedirect(HttpServletRequest request,String accessToken,String redirect) {
        	logger.debug("---------服务端端/serverRedirect----------------------------------------------------------------------------------");
    		
        	try {
    			String hostStr = httpRequestHelper.getUrlContextPath(redirect);
    			Client client = clientMapper.findByClientHost(hostStr);
    			if(client==null)
    			{
    				//#TODO client 查找失败
    				return "找不到客户端信息";
    			}
    			logger.debug("redirect:"+client.getWriteSessionUri()+"?accessToken="+accessToken+"&redirect="+redirect);
    			return "redirect:"+client.getWriteSessionUri()+"?accessToken="+accessToken+"&redirect="+redirect;
    		} catch (Exception e) {
    			logger.error(ExceptionUtils.getMessage(e));
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}
    		return null;
        }
        
    
    	@RequestMapping(value = "/logout")
        public Object logout(HttpServletRequest request,@RequestParam("access_token") String accessToken)
        {
    		JsonResult result = new JsonResult();	
    		try	{
    	        //获取用户名
    	        String username = oAuthService.getUsernameByAccessToken(accessToken);
    	        if(username!=null && username.length()>0)	        
    	        {
    	 	        oAuthService.removeAccessToken(accessToken.toString());	 	        
    	 	        shiroSecurityHelper.kickOutUser(username);
    	        }
    		}catch(Exception e)
    		{
    			logger.error(ExceptionUtils.getMessage(e));
    			e.printStackTrace();
    			result.setCode(ResponseCodes.SYSTEM_ERROR);
    		}
    		return new ResponseEntity(result.toString(), HttpStatus.OK);
        }
    }
    

      OAuth2ApiController.java

    package demo.sso.controller;
    
    import javax.servlet.http.HttpServletRequest;
    import org.apache.oltu.oauth2.common.message.types.ParameterStyle;
    import org.apache.oltu.oauth2.rs.request.OAuthAccessResourceRequest;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import demo.sso.ResponseCodes;
    import demo.sso.model.JsonResult;
    import demo.sso.server.OAuthService;
    import demo.sso.utils.ExceptionUtils;
    
    @Controller
    @RequestMapping("/v1/oauth2/api")
    public class OAuth2ApiController {
    	
        @Autowired
        private OAuthService oAuthService;
        
    	private static final Logger logger = LoggerFactory.getLogger(OAuth2ApiController.class);
        	
    	@RequestMapping(value = "/getUsername")
        public Object getUsername(HttpServletRequest request)
        {
    		JsonResult result = new JsonResult();	
    		try	{
    			 //构建OAuth资源请求
    	        OAuthAccessResourceRequest oauthRequest = new OAuthAccessResourceRequest(request, ParameterStyle.QUERY);
    
    	        //获取Access Token
    	        String accessToken = oauthRequest.getAccessToken();
    
    	        //获取用户名
    	        String username = oAuthService.getUsernameByAccessToken(accessToken);
    	        if(username==null)
    	        {
    	        	result.setCode(ResponseCodes.INVALID_ACCESS_TOKEN);
    	        	logger.debug(accessToken+" 找不到对应的用户");
    	        }
    	        else
    	        {
    	        	result.setData(username);
    	        }
    	        
    		}catch(Exception e)
    		{
    			logger.error(ExceptionUtils.getMessage(e));
    			result.setCode(ResponseCodes.SYSTEM_ERROR);
    		}
    		return new ResponseEntity(result.toString(), HttpStatus.OK);
        }
    }
    

      

    二、Client端代码

    LoginController.java

    package wo.hut.user.web;
    
    import javax.naming.AuthenticationException;
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.LockedAccountException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;
    
    import wo.hut.user.helpers.HttpRequestHelper;
    import wo.hut.user.helpers.ShiroSecurityHelper;
    import wo.hut.user.service.UserService;
    
    
    @Controller
    public class LoginController {
    	@Autowired
    	private HttpRequestHelper httpRequestHelper;
    	@Autowired
    	private UserService userService;
    		@Autowired
    	private ShiroSecurityHelper shiroSecurityHelper;
    		
    	@RequestMapping("/login")
    	public Object login(HttpServletRequest req){
    		if(shiroSecurityHelper.isAuthenticated())
    		{
    			return "redirect:/";
    		}
    		if(shiroSecurityHelper.isAuthenticated())
    		{
    	        ModelAndView mav=new ModelAndView("login");
    	        mav.addObject("error", "您登录,请勿重复登录");
    			return mav;
    		}
    		
    		String error=null;
    		String exceptionClassName = (String)req.getAttribute("shiroLoginFailure");
            if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
                error = "账号不正确!";
            } else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
                error = "密码不正确!";
            } else if(LockedAccountException.class.getName().equals(exceptionClassName)) {
                error = "账号被锁定!";
            } else if(AuthenticationException.class.getName().equals(exceptionClassName)) {
                error = "登录失败!!";
            } else if(exceptionClassName != null) {
                error = "登录失败:" + exceptionClassName;
            }
            ModelAndView mav=new ModelAndView("login");
            mav.addObject("error", error);
    		return mav;
    	}
    		
    	@RequestMapping("/logout")
    	public String logout(HttpServletRequest request,String redirect,ModelMap model)
    	{
    		System.out.println("---------客户端/logout----------------------------------------------------------------------------------");
    		
    		if(redirect==null || redirect.length()<=0)
    		{			
    			redirect = "/";
    		}		
    		
    		shiroSecurityHelper.logout();
    		
    		return "redirect:"+redirect;
    	}
    }
    

      

    OAuth2Controller.java

    package wo.hut.user.web;
    
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLEncoder;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.apache.oltu.oauth2.client.OAuthClient;
    import org.apache.oltu.oauth2.client.URLConnectionClient;
    import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
    import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
    import org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse;
    import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
    import org.apache.oltu.oauth2.common.OAuth;
    import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
    import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
    import org.apache.oltu.oauth2.common.message.types.GrantType;
    import org.apache.oltu.oauth2.common.message.types.ResponseType;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.mvc.support.RedirectAttributes;
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.TypeReference;
    
    import wo.hut.common.utils.ExceptionUtils;
    import wo.hut.user.entity.OAuth2User;
    import wo.hut.user.helpers.HttpRequestHelper;
    import wo.hut.user.helpers.ShiroSecurityHelper;
    import wo.hut.user.helpers.VerifyCodeHelper;
    import wo.hut.user.model.JsonResult;
    import wo.hut.user.service.UserService;
    import wo.hut.user.shiro.token.CustomToken;
    
    @Controller
    @RequestMapping("/v1/oauth2")
    public class OAuth2Controller {
    	@Value("${oauth2.CLIENT_ID}")
    	private String CLIENT_ID 							= "3440CE11-D067-411D-90D0-AA60B88D4A74"; // 应用id CLIENT_ID
    	@Value("${oauth2.CLIENT_SECRET}")
    	private String CLIENT_SECRET 						= "03D609C8-ECFC-4E4A-A0CA-87AD0CBD01A4"; // 应用secret CLIENT_SECRET
    	private String OAUTH_CLIENT_SESSION_URI 			= "/v1/oauth2/writeSession"; // 客户端写入 session 地址
    	private String OAUTH_CLIENT_REDIRECT_URI			= "/v1/oauth2/serverRedirectCallbackCode";//客户端跳转回调地址
    	private String OAUTH_CLIENT_AUTHOIAZE_URI 			= "/v1/oauth2/authorize"; // 客户端用户授权
    	@Value("${oauth2.OAUTH_SERVICE_API}")
    	private String OAUTH_SERVICE_API 					= "http://localhost:8180/demo.sso/v1/oauth2/api/getUsername"; // 测试开放数据api
    	@Value("${oauth2.OAUTH_SERVICE_LOGOUT}")
    	private String OAUTH_SERVICE_LOGOUT 				= "http://localhost:8180/demo.sso/v1/oauth2/logout"; // 测试开放数据api
    	@Value("${oauth2.OAUTH_SERVICE_REDIRECT_SESSION_URI}")
    	private String OAUTH_SERVICE_REDIRECT_SESSION_URI 	= "http://localhost:8180/demo.sso/v1/oauth2/serverRedirect"; // 服务端 session 写入中转地址
    	@Value("${oauth2.OAUTH_SERVER_TOKEN_URL}")
    	private String OAUTH_SERVER_TOKEN_URL 				= "http://localhost:8180/demo.sso/v1/oauth2/accessToken"; // ACCESS_TOKEN获取地址
    	@Value("${oauth2.OAUTH_SERVER_URL}")
    	private String OAUTH_SERVER_URL 					= "http://localhost:8180/demo.sso/v1/oauth2/authorize"; // 服务端授权地址
    	@Value("${oauth2.OAUTH_SERVER_CHECK_ACCESS_CODE_URL}")
    	private String OAUTH_SERVER_CHECK_ACCESS_CODE_URL   = "http://localhost:8180/demo.sso/v1/oauth2/checkAccessToken";//验证token是否有效
    	@Autowired
    	private HttpRequestHelper httpRequestHelper;
    	@Autowired 
    	private VerifyCodeHelper verifyCodeHelper;
    	@Autowired
    	private UserService userService; 
    	@Autowired
    	private ShiroSecurityHelper shiroSecurityHelper;
    	
    	private static final Logger logger = LoggerFactory.getLogger(OAuth2Controller.class);
    	
    	@RequestMapping("/logout")
    	public String logout(HttpServletRequest request,String redirect,ModelMap model)
    	{
    		logger.debug("---------客户端/logout----------------------------------------------------------------------------------");
    		
    		if(redirect==null || redirect.length()<=0)
    		{			
    			redirect = httpRequestHelper.getCobineUrl(request, "/login");
    		}		
    		
    
    		String accessToken=shiroSecurityHelper.getAccessToken();
    		shiroSecurityHelper.logout();
    		if(accessToken==null || accessToken.length()==0)
    		{
    			logger.debug("没有 accessToken ,直接退出。"+redirect);
    			return "redirect:"+redirect;
    		}
    		OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
    		try {
    			logger.debug(OAUTH_SERVICE_LOGOUT);
    	        OAuthClientRequest userInfoRequest = new OAuthBearerClientRequest(OAUTH_SERVICE_LOGOUT)
    	        .setAccessToken(accessToken).buildQueryMessage();
    	        OAuthResourceResponse resourceResponse = oAuthClient.resource(userInfoRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
    	        String jsonStr = resourceResponse.getBody();
    	        
    	        JsonResult result = JSON.parseObject(jsonStr, new TypeReference<JsonResult>() {});
    	        if(result==null ||!result.success())
    	        {
    	        	//#TODO 获取 oauth 服务器资源失败,跳转到提示页面
    	        	logger.debug( jsonStr+" 向  server 退出登录失败" );
    	        	model.addAttribute("message", "向  server 退出登录失败");
    	        }
    		}catch(Exception ex)
    		{
    			logger.error(ExceptionUtils.getMessage(ex));
    			ex.printStackTrace();
    			model.addAttribute("message", ex.toString());
    		}
    		return "redirect:"+redirect;
    	}
    
    	/**
    	 * 客户端跳转中转地址
    	 * @param request
    	 * @param response
    	 * @param attr
    	 * @param redirect
    	 * @return
    	 * @throws OAuthProblemException
    	 */
    	@RequestMapping("/serverRedirect")
    	public String serverRedirect(HttpServletRequest request, HttpServletResponse response, RedirectAttributes attr
    			,String redirect)  throws OAuthProblemException
    	{
    		logger.debug("---------客户端/serverRedirect----------------------------------------------------------------------------------");
    		//OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
    		String redirectUri=httpRequestHelper.getCobineUrl(request, OAUTH_CLIENT_REDIRECT_URI+"?redirect="+redirect);
    		String requestUrl = null;
    		try {
    			//存在 accessToken ,则直接跳转到 sso 重定向页面
    			String accessToken = shiroSecurityHelper.getAccessToken();
    			if(accessToken!=null)
    			{
    				URL checkAccessTokenUrl = new URL(OAUTH_SERVER_CHECK_ACCESS_CODE_URL+"?accessToken=" + accessToken);
    				logger.debug(checkAccessTokenUrl.toString());
    		        HttpURLConnection conn = (HttpURLConnection) checkAccessTokenUrl.openConnection();
    		        conn.setRequestMethod("POST");
    		        conn.disconnect();
    		        if(HttpServletResponse.SC_OK == conn.getResponseCode())
    		        {
    		        	String url=OAUTH_SERVICE_REDIRECT_SESSION_URI+"?accessToken="+accessToken+"&redirect="+URLEncoder.encode( redirect);
    		            logger.debug("redirect:"+url);
    		            return "redirect:"+url;    
    		        }
    			}
    			else
    			{
    				shiroSecurityHelper.removeAccessToken();
    			}
    			logger.debug(OAUTH_SERVER_URL);
    			//构建oauthd的请求。设置请求服务地址(accessTokenUrl)、clientId、response_type、redirectUrl
    			OAuthClientRequest accessTokenRequest = OAuthClientRequest
    					.authorizationLocation(OAUTH_SERVER_URL)
    			        .setResponseType(ResponseType.CODE.toString())
    			        .setClientId(CLIENT_ID)
    			        .setRedirectURI(redirectUri)
    			        .buildQueryMessage();
    			requestUrl = accessTokenRequest.getLocationUri();
    		} catch (Exception e) {
    			e.printStackTrace();
    			logger.error(ExceptionUtils.getMessage(e));
    		}
    		logger.debug("redirect:"+requestUrl );
    		return "redirect:"+requestUrl ;
    	}
    
    	/**
    	 * 客户端跳转回调验证地址
    	 */
    	@RequestMapping("/serverRedirectCallbackCode")
    	public Object serverRedirectCallbackCode(HttpServletRequest request, HttpServletResponse response, RedirectAttributes attr
    			,String redirect) throws OAuthProblemException
    	{
    		logger.debug("---------客户端/serverRedirectCallbackCode----------------------------------------------------------------------------------");
    		HttpServletRequest httpRequest = (HttpServletRequest) request;
    	    String code = httpRequest.getParameter("code"); 
    	    System.out.println(code);
    	    OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
    	    try {
    	    	logger.debug(OAUTH_SERVER_TOKEN_URL);
    			OAuthClientRequest accessTokenRequest = OAuthClientRequest
    					.tokenLocation(OAUTH_SERVER_TOKEN_URL)
    			        .setGrantType(GrantType.AUTHORIZATION_CODE)
    			        .setClientId(CLIENT_ID)
    			        .setClientSecret(CLIENT_SECRET)
    			        .setCode(code)
    			        .setRedirectURI(OAUTH_SERVER_TOKEN_URL)
    			        .buildQueryMessage();
    			
    			//去服务端请求access token,并返回响应
    			OAuthAccessTokenResponse oAuthResponse = oAuthClient.accessToken(accessTokenRequest, OAuth.HttpMethod.POST);
    			//获取服务端返回过来的access token 
    			String accessToken = oAuthResponse.getAccessToken();
    			//查看access token是否过期
                //Long expiresIn = oAuthResponse.getExpiresIn();
                shiroSecurityHelper.setAccessToken(accessToken);
                
                String url="redirect:"+OAUTH_SERVICE_REDIRECT_SESSION_URI+"?accessToken="+accessToken+"&redirect="+URLEncoder.encode( redirect);
                logger.debug(url);
                return url;            
    		} catch (OAuthSystemException e) {
    			e.printStackTrace();
    			logger.error(ExceptionUtils.getMessage(e));
    		}
    	    return new ResponseEntity("sso登录失败!", HttpStatus.OK);
    	}
    	
    	/**
    	 * sso 向客户端写入session 地址
    	 * @param request
    	 * @param accessToken
    	 * @param redirect
    	 * @return
    	 */
    	@RequestMapping("/writeSession")
    	public Object writeSession(HttpServletRequest request,HttpServletResponse response,String accessToken,String redirect) 
    	{
    		logger.debug("---------客户端/writeSession----------------------------------------------------------------------------------");
    		
    		if(shiroSecurityHelper.isAuthenticated())
    		{
    			shiroSecurityHelper.setAccessToken(accessToken);
    	        logger.debug( "已经登录,redirect:"+redirect );
    	        return "redirect:"+redirect ;
    		}
    		
    		OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
    		try {
    			logger.debug(OAUTH_SERVICE_API);
    	        OAuthClientRequest userInfoRequest = new OAuthBearerClientRequest(OAUTH_SERVICE_API)
    	        .setAccessToken(accessToken).buildQueryMessage();
    	        OAuthResourceResponse resourceResponse = oAuthClient.resource(userInfoRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
    	        String jsonStr = resourceResponse.getBody();
    	        
    	        JsonResult result = JSON.parseObject(jsonStr, new TypeReference<JsonResult>() {});
    	        if(result==null || !result.success())
    	        {
    	        	//#TODO 获取 oauth 服务器资源失败,跳转到提示页面
    	        	logger.info( jsonStr+" json 转换失败,redirect:"+redirect );
    		        return "redirect:"+redirect ;
    	        }
    	        String ssoUsername = result.getData().toString();
    	        //根据SSO 的 username 查找对应的用户信息,查询不到表示 sso 和 wo+用户未做关联
    	        OAuth2User user = userService.findBySsoUsername(ssoUsername);
    	        
    	        
    	        //创建关联关系
    	        if (user==null) {	        	
    	        	//#TODO 客户端检查 UserMapping 信息失败,跳转到提示页面
    	        	logger.warn(ssoUsername+"---------------user mapping can not find.");
    	        	String url="redirect:"+httpRequestHelper.getCobineUrl(request, OAUTH_CLIENT_AUTHOIAZE_URI)+"?accessToken="+accessToken+"&redirect="+URLEncoder.encode( redirect);
    	        	logger.debug(url);
    				return url;
    	        }
    	        
    	        //写入登录session 	       
            	CustomToken token = new CustomToken(user.getUsername());
    			shiroSecurityHelper.login(token);
    			shiroSecurityHelper.setLoginInfo(user);
    			shiroSecurityHelper.setAccessToken(accessToken);
    	        
    	        logger.debug( "redirect:"+redirect );
    	        return "redirect:"+redirect ;
    
    		} catch (Exception e) {
    			e.printStackTrace();
    			logger.error(ExceptionUtils.getMessage(e));
    		}
    		return new ResponseEntity("sso登录失败!", HttpStatus.OK);
    	}
    	/**
    	   *  客户端授权用户接入到sso页面,需要验证登录
    	 * @param request
    	 * @param accessToken
    	 * @param redirect
    	 * @param model
    	 * @return
    	 */
    	@RequestMapping("/authorize")
    	public Object authorize(HttpServletRequest request,String accessToken,String redirect,ModelMap model)
    	{
    		logger.debug("---------客户端/authorize----------------------------------------------------------------------------------");
    		
    		if(!isLogin(request))
    		{
    			try	{
    				String url=httpRequestHelper.getCobineUrl(request,"/login?returnUrl="+URLEncoder.encode(httpRequestHelper.getRequestUrl(request), "UTF-8"));
    	        	return "redirect:"+url;
    			}catch(Exception e)
    			{
    				return null;
    			}
    		}
    		
    		if ("get".equalsIgnoreCase(request.getMethod())) {
    			model.addAttribute("message", "是否允许用户 "+shiroSecurityHelper.getUsername()+" 关联到【OAuth2 认证中心】?");
    			return "v1/oauth2/authorize";
    		}
    		else
    		{
    			
    			OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
    			try {
    				HttpSession session = request.getSession();
    				logger.debug(OAUTH_SERVICE_API);
    		        OAuthClientRequest userInfoRequest = new OAuthBearerClientRequest(OAUTH_SERVICE_API)
    		        .setAccessToken(accessToken).buildQueryMessage();
    		        OAuthResourceResponse resourceResponse = oAuthClient.resource(userInfoRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
    		        String jsonStr = resourceResponse.getBody();
    		        
    		        JsonResult result = JSON.parseObject(jsonStr, new TypeReference<JsonResult>() {});
    		        if(result==null ||!result.success())
    		        {
    		        	//#TODO 获取 oauth 服务器资源失败,跳转到提示页面
    		        	logger.debug( jsonStr+" 向  server 获取用户信息失败" );
    		        	model.addAttribute("message", "向  server 获取用户信息失败");
    		        	return "authorization/authorize";
    		        }
    		        String ssoUsername = result.getData().toString();
    				String username = shiroSecurityHelper.getUsername();
    				
    				boolean flag = userService.insertMapping(username, ssoUsername);
    				if(!flag)
    				{
    					logger.debug( jsonStr+" 插入 oauth_mapping 失败" );
    					System.out.println( jsonStr+" 插入 oauth_mapping 失败" );
    				}
    			}catch(Exception ex)
    			{
    				model.addAttribute("message", ex.toString());
    				return "v1/oauth2/authorize";
    			}
    			logger.debug("redirect:"+httpRequestHelper.getCobineUrl(request, OAUTH_CLIENT_SESSION_URI)+"?accessToken="+accessToken+"&redirect="+URLEncoder.encode( redirect));
    			return "redirect:"+httpRequestHelper.getCobineUrl(request, OAUTH_CLIENT_SESSION_URI)+"?accessToken="+accessToken+"&redirect="+URLEncoder.encode( redirect);
    		}
    	}
    	
    	/**
    	 * 检查是否登录
    	 * @param request
    	 * @return
    	 */
    	private boolean isLogin(HttpServletRequest request)
    	{
    		return shiroSecurityHelper.isAuthenticated();
    	}
    }
    

      

    ClientService.java

    package demo.sso.server;
    
    import java.util.List;
    import demo.sso.entity.Client;
    import demo.sso.entity.User;
    
    
    public interface ClientService {
    
        Client createClient(Client client);
    
        Client updateClient(Client client);
    
        void deleteClient(Long clientId);
        
        void logicalDeleteClient(Long clientId);
    
        List<Client> findAll();
        
        Client findById(Long id);
        
        Client findByClientId(String clientId);
    
        Client findByClientSecret(String clientSecret);
        boolean canCreateClient(Client client);
    	boolean canUpdateClient(Client client);	
    }
    

      

    OAuthService.java

    package demo.sso.server;
    
    public interface OAuthService {
    
        //添加 auth code
        void addAuthCode(String authCode, String username);
        
        void removeAuthCode(String authCode);
    
        //添加 access token
        void addAccessToken(String accessToken, String username);
        
        void removeAccessToken(String accessToken);
    
        //验证auth code是否有效
        boolean checkAuthCode(String authCode);
    
        //验证access token是否有效
        boolean checkAccessToken(String accessToken);
    
        String getUsernameByAuthCode(String authCode);
    
        String getUsernameByAccessToken(String accessToken);
    
        //auth code / access token 过期时间
        long getExpireIn();
    
        boolean checkClientId(String clientId);
    
        boolean checkClientSecret(String clientSecret);
    
    
    }
    

      

    PermissionService.java

    package demo.sso.server;
    
    import java.util.List;
    import demo.sso.entity.Permission;
    
    public interface PermissionService {
    	Long addPermission(Permission permission);
    	void deletePermission(Long permissionId);
    	void deleteMorePermissions(Long...permIds);
    	Permission findById(Long permId);
    	List<Permission> getPermissionsByRoleId(Long roleId);
    	List<Permission> getAllPermissions();
    	void updatePermission(Permission permission);
    }
    

      RoleService.java

    package demo.sso.server;
    
    import java.util.List;
    import demo.sso.entity.Role;
    
    public interface RoleService {
    	Long addRole(Role role,Long...permissionIds);
    	void deleteRole(Long roleId);
    	void deleteMoreRoles(Long...roleIds);
    	Role getRoleById(Long roleId);
    	List<Role> getRolesByUserName(String userName);
    	List<Role> getAllRoles();
    	void updateRole(Role role,Long...permIds);
    	void addRolePermissions(Long roleId,Long...permissionIds);
    }
    

      

    UserService.java

    package demo.sso.server;
    
    
    import java.util.List;
    import java.util.Set;
    
    import demo.sso.entity.User;
    import demo.sso.model.AdminUserSearchModel;
    import demo.sso.model.Navigation;
    import demo.sso.model.PageInfo;
    
    public interface UserService {
    	boolean canCreateUser(User user);
        User createUser(User user);
        boolean canUpdateUser(User user);
        boolean updateUser(User user);    
        void deleteUser(Long userId);
        void logicalDeleteUser(Long userId);
        void changePassword(Long userId, String newPassword);
        boolean changePassword(Long userId,String oldPassword,String newPassword);
        List<User> findAll();
        PageInfo<User> adminUserSearchList(AdminUserSearchModel search);
        User findByUsername(String username);
        User findByPhone(String phone);
        User findById(Long id);
        Set<String> findRolesByUserName(String userName);
        Set<String> findPermissionsByUserName(String userName);
        List<Navigation> getNavigationBar(String userName);
        boolean updateCode(String phone,String code);
        
    }
    

      

    具体DB层代码,就不上了。

    转Java 才几月,好多地方不完善,有发现问题,请多多指教。

  • 相关阅读:
    底部菜单栏之Fragment的详细介绍和使用方法
    Warm up 2
    如何做好一位资深的web前端工程师
    使用 HTML5 canvas 绘制精美的图形
    计算元素距离浏览器左边的距离
    [JSOI2016]独特的树叶
    【SDOI2009】Elaxia的路线
    【SCOI2009】最长距离
    【SCOI2009】围豆豆
    【AHOI2005】穿越磁场
  • 原文地址:https://www.cnblogs.com/hujunmin/p/10333291.html
Copyright © 2020-2023  润新知