接 spring security 单点登录 简单实现
spring security 这个页面非常不爽,哪有每次登录都点一下的到来。今天咱就说下怎么在不同情况下处理这个页面是否弹出
通过查看源码,发现这个页面是由
WhitelabelApprovalEndpoint 中 控制的
@RequestMapping({"/oauth/confirm_access"}) public ModelAndView getAccessConfirmation(Map<String, Object> model, HttpServletRequest request) throws Exception { String template = this.createTemplate(model, request); if(request.getAttribute("_csrf") != null) { model.put("_csrf", request.getAttribute("_csrf")); } return new ModelAndView(new SpelView(template), model); }
那咱就新建一个一模一样的类 覆盖她的url
/** * 覆盖授权页面手动提交问题 * 自动授权 * Created by zhaoyanzeng on 2019/2/25. */ @RestController @SessionAttributes({"authorizationRequest"}) public class SsoApprovalEndpoint { private static String CSRF = "<input type=\'hidden\' name=\'${_csrf.parameterName}\' value=\'${_csrf.token}\' />"; private static String DENIAL = "<form id=\'denialForm\' name=\'denialForm\' action=\'${path}/oauth/authorize\' method=\'post\'><input name=\'user_oauth_approval\' value=\'false\' type=\'hidden\'/>%csrf%<label><input name=\'deny\' value=\'Deny\' type=\'submit\'/></label></form>"; //将生成授权页面隐藏,改为表单自动提交 private static String TEMPLATE = "<html><body><div style='display:none;'>" + "<h1>OAuth Approval</h1><p>Do you authorize \'${authorizationRequest.clientId}\' to access your protected resources?</p><form id=\'confirmationForm\' name=\'confirmationForm\' action=\'${path}/oauth/authorize\' method=\'post\'><input name=\'user_oauth_approval\' value=\'true\' type=\'hidden\'/>%csrf%%scopes%<label><input name=\'authorize\' value=\'Authorize\' type=\'submit\'/></label></form>%denial%</div>" + "</body><script>document.getElementById('confirmationForm').submit()</script></html>"; //第三方认证的时候,弹出的页面,跟原来页面一样 private static String TEMPLATE_THIRD= "<html><body>" + "<h1>OAuth Approval</h1><p>Do you authorize \'${authorizationRequest.clientId}\' to access your protected resources?</p><form id=\'confirmationForm\' name=\'confirmationForm\' action=\'${path}/oauth/authorize\' method=\'post\'><input name=\'user_oauth_approval\' value=\'true\' type=\'hidden\'/>%csrf%%scopes%<label><input name=\'authorize\' value=\'Authorize\' type=\'submit\'/></label></form>%denial%" + "</body></html>"; private static String SCOPE = "<li><div class=\'form-group\'>%scope%: <input type=\'radio\' name=\'%key%\' value=\'true\'%approved%>Approve</input> <input type=\'radio\' name=\'%key%\' value=\'false\'%denied%>Deny</input></div></li>"; public SsoApprovalEndpoint() { } @RequestMapping({"/oauth/confirm_access"}) public ModelAndView getAccessConfirmation(Map<String, Object> model, HttpServletRequest request) throws Exception { String template = this.createTemplate(model, request); if (request.getAttribute("_csrf") != null) { model.put("_csrf", request.getAttribute("_csrf")); } return new ModelAndView(new SsoSpelView(template), model); } protected String createTemplate(Map<String, Object> model, HttpServletRequest request) { String template = ""; //判断是第三方认证还是单点登录认证 这个是你需要第三方认证的时候自行添加的参数 String client_type = request.getParameter("clientType"); if(StringUtils.equals(client_type,"third")){ template= TEMPLATE_THIRD; }else { template= TEMPLATE; } ; if (!model.containsKey("scopes") && request.getAttribute("scopes") == null) { template = template.replace("%scopes%", "").replace("%denial%", DENIAL); } else { template = template.replace("%scopes%", this.createScopes(model, request)).replace("%denial%", ""); } if (!model.containsKey("_csrf") && request.getAttribute("_csrf") == null) { template = template.replace("%csrf%", ""); } else { template = template.replace("%csrf%", CSRF); } return template; } private CharSequence createScopes(Map<String, Object> model, HttpServletRequest request) { StringBuilder builder = new StringBuilder("<ul>"); Map scopes = (Map) ((Map) (model.containsKey("scopes") ? model.get("scopes") : request.getAttribute("scopes"))); Iterator var5 = scopes.keySet().iterator(); while (var5.hasNext()) { String scope = (String) var5.next(); String approved = "true".equals(scopes.get(scope)) ? " checked" : ""; String denied = !"true".equals(scopes.get(scope)) ? " checked" : ""; String value = SCOPE.replace("%scope%", scope).replace("%key%", scope).replace("%approved%", approved).replace("%denied%", denied); builder.append(value); } builder.append("</ul>"); return builder.toString(); } }
新建一个SsoSpelView 复制原SpelView
/** * Created by zhaoyanzeng on 2019/2/25. */ public class SsoSpelView implements View { private final String template; private final String prefix; private final SpelExpressionParser parser = new SpelExpressionParser(); private final StandardEvaluationContext context = new StandardEvaluationContext(); private PropertyPlaceholderHelper.PlaceholderResolver resolver; public SsoSpelView(String template) { this.template = template; this.prefix = (new RandomValueStringGenerator()).generate() + "{"; this.context.addPropertyAccessor(new MapAccessor()); this.resolver = new PropertyPlaceholderHelper.PlaceholderResolver() { public String resolvePlaceholder(String name) { Expression expression = SsoSpelView.this.parser.parseExpression(name); Object value = expression.getValue(SsoSpelView.this.context); return value == null?null:value.toString(); } }; } public String getContentType() { return "text/html"; } public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { HashMap map = new HashMap(model); String path = ServletUriComponentsBuilder.fromContextPath(request).build().getPath(); map.put("path", path == null?"":path); this.context.setRootObject(map); String maskedTemplate = this.template.replace("${", this.prefix); PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper(this.prefix, "}"); String result = helper.replacePlaceholders(maskedTemplate, this.resolver); result = result.replace(this.prefix, "${"); response.setContentType(this.getContentType()); response.getWriter().append(result); } }
好了,现在就可以直接跳转不需要授权页面点一下了。