场景与实现逻辑

  • 我的登录接口,在输入账号密码成功后进行中间页
  • 中间页可以通过添加Authenticator的实现类来写逻辑
  • authenticate方法是渲染页面的,action方法是提交表单后的逻辑
  • context.success()方法表示认证成功,将进行重写向操作
  • 可以通过Response.status(302).header(HttpHeaders.LOCATION, modifyPasswordPage).build()实现自定义的重定向地址
  • 在kc配置中,复制一个brower认证流,为账号密码模块添加一个行为(execution)

核心代码

  @Override
public void authenticate(AuthenticationFlowContext context) { if (context.getAuthenticationSession().getUserSessionNotes().containsKey("password")) {
String password = context.getAuthenticationSession().getUserSessionNotes().get("password").toLowerCase();
if (password.matches(regex)) {
context.success();
return;
}
} Response challenge = context.form().createForm("login-simple-password-alert.ftl");
context.challenge(challenge);
} @Override
public void action(AuthenticationFlowContext context) {
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
if (formData.containsKey("submitType") && formData.get("submitType").get(0).equals("1")) {
AuthenticatorConfigModel authenticatorConfigModel =
KeycloakUtil.getAuthenticatorConfigByAlias(context.getSession(), V6_CONFIG);
String mainSite = "https://www.abc.com";
if (authenticatorConfigModel.getConfig().containsKey(MAIN_SITE) &&
StringUtils.isNotBlank(authenticatorConfigModel.getConfig().get(MAIN_SITE))) {
mainSite = authenticatorConfigModel.getConfig().get(MAIN_SITE);
}
if (mainSite.endsWith("/")) {
mainSite = mainSite.substring(0, mainSite.length() - 1);
}
context.success();
String modifyPasswordPage = mainSite + "/usercenter/info";
Response response = Response.status(302)
.header(HttpHeaders.LOCATION, modifyPasswordPage).build();
context.challenge(response);
return;
}
context.success();
}

登录中间页面login-simple-password-alert.ftl

  • src\main\resources\theme\custom\login\
  • 这个目录下有皮肤文件login.ftl和中间页文件login-simple-password-alert.ftl
  • kc后台为指定客户端或者领域设置登录皮肤为custom
  • login-simple-password-alert.ftl如下:
<form id="kc-form-login" action="${url.loginAction}" method="post">
<input type="hidden" id="submitType" name="submitType" value="0">
<a class="btn-register" href="javascript:void(0)" onclick="submit(0)">默认登录后的跳换</a>
<a class="btn-register" href="javascript:void(0)" onclick="submit(1)">登录后去个人中心</a>
</form> <script>
function submit(val) {
document.getElementById("submitType").value=val;
document.getElementById('kc-form-login').submit();
}
</script>

自定义登录逻辑的KC配置如下

keycloak~在认证的action中自定义重定向地址的更多相关文章

  1. struts 中自定义action访问方法

    struts中action类继承了ActionSupport  默认实现了execute()方法 struts.xml配置文件中 然后可以配置如下映射: <package name =" ...

  2. 24SpringMvc中的重定向和转发-解释return "redirect:/cargo/contractproduct/tocreate.action";

    我在做JK项目时发现:我们在增加一个货物时.会先根据提交的Action()进入到一个新增页面 //跳转到新增的页面 @RequestMapping("/cargo/contractprodu ...

  3. Asp.net Core 系列之--5.认证、授权与自定义权限的实现

    ChuanGoing 2019-11-24 asp.net core系列已经来到了第五篇,通过之前的基础介绍,我们了解了事件订阅/发布的eventbus整个流程,初探dapper ORM实现,并且简单 ...

  4. Action中动态方法的调用 Action中通配符的使用 Result的配置

       Action中动态方法的调用 动态方法调用(Dynamic Method Invocation,DMI) 标识符:! 一.通过以下选中的文件来查看是否禁止调用动态方法

  5. C#开发微信门户及应用(14)-在微信菜单中采用重定向获取用户数据

    我曾经在系列文章中的<C#开发微信门户及应用(11)--微信菜单的多种表现方式介绍>中介绍了微信菜单里面的重定向操作,通过这个重定向操作,我们可以获取一个code值,然后获取用户的open ...

  6. 第三章Struts2 Action中动态方法调用、通配符的使用

    01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...

  7. 在Action 中访问web资源

    1.什么是web资源: HttpServletRequest,HttpSession,ServletContext等原生的Servlet API. 2.为什么要访问web资源? B/S应用的Contr ...

  8. struts2配置文件中Action中的各属性的含义

    StrutsApacheBeanJSPServlet attribute:      这个属性用来指定ActionForm保存到指定上下文时所使用的属性名.如果不指定attribute属性的值,将使用 ...

  9. Struts2 Action中动态方法调用、通配符的使用

    一.Struts2执行过程图: 二.struts2配置文件的加载顺序 struts-default.xml---struts-plugin.xml---struts.xml 具体步骤: 三.Actio ...

  10. struts2中怎么把action中的值传递到jsp页面

    对于如何把struts2的action中的值传到jsp页面中,主要的方法有2种: 使用转发视图利用request域中储存所需的值 使用重定向时存储数据进入session使其在jsp中可以获得 下面,让 ...

随机推荐

  1. 了解企业架构EA(Enterprise Architecture)

    一.企业架构简介 企业架构:Enterprise Architecture,EA,或企业体系结构,是在信息系统架构设计与实践基础上发展起来的一个特殊领域. 但是企业架构现在还没有一个公认的定义,综合现 ...

  2. 多线程系列(八) -ReentrantLock基本用法介绍

    一.简介 在之前的线程系列文章中,我们介绍到了使用synchronized关键字可以实现线程同步安全的效果,以及采用wait().notify()和notifyAll()方法,可以实现多个线程之间的通 ...

  3. ROS2 humble交叉编译环境配置

    目录 配置 toolchain文件: 库文件 交叉编译指令: 问题点: 1.find_package找不到自定义依赖包的问题 2.libarmadillo.so.10: undefined refer ...

  4. goroutine并发

    每一个并非的执行单元叫作一个goroutine.设想这里的一个程序有两个函数,一个函数做计算,另一个输出结果,假设两个函数没有相互之间的调用关系.一个线性的程序会先调用其中的一个函数,然后再调用另一个 ...

  5. djang中文件上传MEDIA路径配置

    1.settings.py文件中配置 # 项目中存储上传文件的根目录[暂时配置],注意,uploads目录需要手动创建否则上传文件时报错 MEDIA_ROOT = os.path.join(BASE_ ...

  6. ASP.NET Core 应用(SignalR)发布到 IIS 报错(HTTP Error 500.19 - Internal Server Error)

    参考资料: ASP.NET Core SignalR 入门 将 ASP.NET Core 应用发布到 IIS Download .NET Core 报错信息: HTTP Error 500.19 - ...

  7. 一文详解云上自动化部署集群管理工具 Nebula Operator

    本文首发于 Nebula Graph 公众号:Nebula Operator 开源啦!一文详解这个云上自动化部署集群管理工具 在介绍 Nebula Operator 之前,让我们先来了解下什么是 Op ...

  8. 关于KMP模式匹配的一些思考

    算法简介 模式匹配 给定主串text和模式串pattern,在主串中查找,如果找到了模式串,返回模式串在主串中的起始位置,从1开始计数. 暴力求解求解模式匹配 算法的核心思想是:蛮力法.即使用两个指针 ...

  9. 微信小程序开发:接入阿里云人像动漫化api接口

    前面我已经把腾讯云的人像转动漫化接口接到了我的小程序里,但是和阿里云的对比后,发现阿里云的效果会更好一些,且支持更多特效,如下: 我比较喜欢这个3D特效风格,动画3D也可以,大家拭目以待. 话说上次接 ...

  10. Educational Codeforces Round 145 (Rated for Div. 2)C. Sum on Subarrays(构造)

    很意思的一道构造题 题意:给一个\(n.k\),让构造长度为n的数组满足,子数组为整数的个数为k个,负数的为\(k-(n+1)* n/2\),每个数的范围为\([-1000,1000]\) 这种构造题 ...