spring-security-oauth2 使用 AuthorizationEndpoint 自定义授权页面

JAVA herman 1949浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

还记得我在这篇文章《SpringBoot + spring-security-oauth2 实现仿微信,QQ,微博等授权认证》中实现的漂亮的授权页面吗?spring-security-oauth2 中默认的授权页面太丑了,基本没人会使用。我们都希望能定制化这个页面,像微信授权页面那样,简单美观。本文,我们就一起来一个定制化 OAuth2 中的授权页面。

漂亮的 OAuth2 授权页

上面这个授权页面,图标,内容都可以高度定制化。

所有的定制化思路都是,找到默认的实现,然后重写默认的实现即可。

默认的授权页面在 org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint 中有定义。代码如下:

private String userApprovalPage = "forward:/oauth/confirm_access";
private String errorPage = "forward:/oauth/error";

然后,我们只需要把我们定制的的授权页面和加载的数据通过 userApprovalPage 和 errorPage 展示即可。

@Configuration  
@EnableAuthorizationServer  
public class AuthorizationServerConfiguration extends 
    AuthorizationServerConfigurerAdapter {  
    @Autowired  
    private AuthorizationEndpoint authorizationEndpoint;  
    @PostConstruct  
    public void init() {  
        authorizationEndpoint.setUserApprovalPage("forward:/oauth/approvale/confirm");
        authorizationEndpoint.setErrorPage("forward:/oauth/approvale/error"); 
    }  
} 

在定义一个 OAuthController,注意这个 Controller 必须要有 @SessionAttributes({ "authorizationRequest" }) 注解。

@Controller
@SessionAttributes({ "authorizationRequest" })
public class OAuthController {
    @RequestMapping({ "/oauth/approvale/confirm" })
    public String getAccessConfirmation(Map<String, Object> model, 
    HttpServletRequest request) throws Exception {
        @SuppressWarnings("unchecked")
        Map<String, String> scopes = (Map<String, String>) (model.containsKey("scopes") ? 
            model.get("scopes") : request.getAttribute("scopes"));
        List<String> scopeList = new ArrayList<String>();
        for (String scope : scopes.keySet()) {
            scopeList.add(scope);
        }
        model.put("scopeList", scopeList);
        return "oauth_approval";
    }
    @RequestMapping({ "/oauth/approvale/error" })
    public String handleError(Map<String, Object> model, HttpServletRequest request) {
        Object error = request.getAttribute("error");
        String errorSummary;
        if (error instanceof OAuth2Exception) {
            OAuth2Exception oauthError = (OAuth2Exception) error;
            errorSummary = HtmlUtils.htmlEscape(oauthError.getSummary());
        } else {
            errorSummary = "Unknown error";
        }
        model.put("errorSummary", errorSummary);
        return "oauth_error";
    }
}

默认的 /oauth/confirm_access 和 /oauth/error 两个请求地址的代码分别在 org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint 和 org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint 中。代码分别如下; 

// WhitelabelApprovalEndpoint 类
@RequestMapping({"/oauth/confirm_access"}) 
public ModelAndView getAccessConfirmation(Map<String, Object> model, 
HttpServletRequest request) throws Exception { 
    // 业余草省略处理逻辑
}
// WhitelabelErrorEndpoint 类
@RequestMapping({"/oauth/error"}) 
public ModelAndView handleError(HttpServletRequest request) { 
    // 业余草省略处理逻辑
}

我们的 oauth_approval.html 页面的代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>授权登录</title>
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"/>
    <link rel="stylesheet" href="//i.gtimg.cn/vipstyle/frozenui/2.0.0/css/frozen.css"/>
    <style>
        .block{
            position: relative;
        }
        .ui-notice{
            position: relative;
            padding:20px 15px;
            box-sizing: border-box;
        }
        .ui-notice p{
            color:#333;
            font-weight: 600;
        }
        .ui-btn-primary{
            background-color: #02cd93;
            border-color:#02cd93;;
        }
        .ui-notice-btn{
            padding:50px 0px 15px;
        }
    </style>
</head>
<body>
<div class="block">
    <section class="ui-notice">
        <i class="icon icon-notice"></i>
        <p>是否授权:<span th:text="${session.authorizationRequest.clientId}">clientId</span></p>
        <div class="ui-notice-btn">
            <form id='confirmationForm' name='confirmationForm' action="/auth/oauth/authorize" method='post'>
                <input name='user_oauth_approval' value='true' type='hidden'/>
                <!--写好授权访问领域-->
                <input th:name="${s}" value="true" type="hidden" th:each="s : ${scopeList}"/>
                <input class="ui-btn-primary ui-btn-lg ui-btn-primary" name='authorize' value='授权' type='submit'/>
                <!-- <input type="radio" name="scope.user_info" value="true">授权</input>
                 <input type="radio" name="scope.user_info" value="false" checked>取消</input> -->
            </form>
        </div>
    </section>
</div>
</body>
</html>

剩下的一个 oauth_error.html 取消授权这个页面,我就不贴了。自己去实现吧。关于自定义登录页面,我们下章再说。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » spring-security-oauth2 使用 AuthorizationEndpoint 自定义授权页面