Grails3-Spring-Secuirty自定义加密方式

Grails3 Spring Secuirty自定义加密方式应用场景公司老项目使用grails2.0+版本,他的加密方式为encodeAsSHA256,数据是通过导入实现,要兼容以前数据加密方式,使以前使用老项目的用户也能用原先的密码登录。首先,我做了一下测试def test() { map.password1 = "123456".encodeAsSHA256() map.password2 = springSecurityService.encodePassword("123456") render map as JSON}结果发现他们是两种不同的加密方式接下来只能通过重写父类方法实现统一加密第一步:自定义一个类,我习惯在src/main/goovy下创建CustomPasswordEncoder.groovy类,也可以创建java类package com.encoderimport org.springframework.security.authentication.encoding.MessageDigestPasswordEncoderimport org.springframework.security.authentication.encoding.PasswordEncoderUtilsimport org.springframework.security.crypto.codec.Heximport org.springframework.util.Assertimport java.security.MessageDigest/** * 自定义加密覆盖默认加密方式 * 项目spring-security版本为3.1.0,本可以重新BaseDigestPasswordEncoder类 * 但是本人看BaseDigestPasswordEncoder类被标记为删除了,所以通过重写MessageDigestPasswordEncoder类方法实现 */class CustomPasswordEncoder extends MessageDigestPasswordEncoder { // 默认为MD5 private String algorithm = "MD5"; // 加密次数(提高安全) private int iterations = 1; CustomPasswordEncoder() { // 当前类默认构造器,因为父类没有空构造器,所以这里必须调用父类有参构造,这里传入参数必须是父类存在的加密规则,否则报错 super("SHA-256") } CustomPasswordEncoder(String algorithm) { super(algorithm, false); this.algorithm = algorithm } CustomPasswordEncoder(String algorithm, boolean encodeHashAsBase64) throws IllegalArgumentException { super() setEncodeHashAsBase64(encodeHashAsBase64); this.algorithm = algorithm; getMessageDigest(); } @Override String encodePassword(String rawPass, Object salt) { String saltedPass = this.mergePasswordAndSalt(rawPass, salt, false) MessageDigest messageDigest = this.getMessageDigest() byte[] digest = messageDigest.digest(saltedPass.getBytes("UTF-8")) for (int i = 1; i < iterations; i++) { digest = messageDigest.digest(digest); } // 先判断是否启用base64 if (this.getEncodeHashAsBase64()) { return new String(Base64.encodeAsBase64(digest)) // 判断是否为自定义的SHA-256-1(框架自定加密方式,非spring security框架,这里指的是grails自带的加密) } else if ("SHA-256-1".equalsIgnoreCase(algorithm)) { return rawPass.encodeAsSHA256() } else { // 使用用户配置的其他加密方式 return new String(Hex.encode(digest)) } } @Override boolean isPasswordValid(String encPass, String rawPass, Object salt) { String pass1 = "" + encPass String pass2 = encodePassword(rawPass, salt) return PasswordEncoderUtils.equals(pass1, pass2) } String getAlgorithm() { return algorithm; } void setIterations(int iterations) { Assert.isTrue(iterations > 0, "Iterations value must be greater than zero"); this.iterations = iterations; }}第二步:在grails-app/conf/spring/resources.groovy中注册一下beanbeans = { // 自定义密码 passwordEncoder(com.encoder.CustomPasswordEncoder) { encodeHashAsBase64 = false // 若为true,则以base64方式加密 }}第三步:在grails-app/conf/application.groovy中添加配置// 原框架加密方式,有SHA-256、bcrypt、MD5、pbkdf2,默认为bcrypt// 自定义加密默认为MD5,这里SHA-256-1为自定义加密,还可以用SHA-256等grails.plugin.springsecurity.password.algoritham = 'SHA-256-1'到这里配置就已经完成了,启动测试注意:项目中用到domain.save(failOnError: true)的有时需要修改为domain.save(flush: true),我测试密码修改时,failOnError: true没有修改成功。参考 ...

June 14, 2019 · 1 min · jiezi

Grails32新增了一些新东西

记录一下一些坑Grails3.2-版可以直接在domain中注入service,在Grails3.2+中默认关闭了自动注入功能开启方式方式一在application.groovy中配置全局映射,若没有此脚本需新建grails.gorm.default.mapping = { autowire true}方式二在需要注入bean的domain中添加映射static mapping = { autowire true}方式三在application.yml中新增或修改配置---grails: gorm: autowire: true参考

June 12, 2019 · 1 min · jiezi

Grails通过sessionId获取session对象

Grails通过sessionId获取session对象思路:自定义一个类用来监听session,所有session存入map中,sessionId作为读取的key创建监听类 SessionTrackerpackage com.sessionimport org.springframework.beans.BeansExceptionimport org.springframework.context.ApplicationContextimport org.springframework.context.ApplicationContextAwareimport org.springframework.web.context.WebApplicationContextimport javax.servlet.http.HttpSessionimport javax.servlet.http.HttpSessionEventimport javax.servlet.http.HttpSessionListenerimport java.util.concurrent.ConcurrentHashMapimport java.util.concurrent.ConcurrentMapclass SessionTracker implements HttpSessionListener, ApplicationContextAware { private static final ConcurrentMap<String, HttpSession> sessions = new ConcurrentHashMap<String, HttpSession>(); void setApplicationContext(ApplicationContext applicationContext) throws BeansException { def servletContext = ((WebApplicationContext) applicationContext).getServletContext() servletContext.addListener(this); } void sessionCreated(HttpSessionEvent httpSessionEvent) { sessions.putAt(httpSessionEvent.session.id, httpSessionEvent.session) } void sessionDestroyed(HttpSessionEvent httpSessionEvent) { sessions.remove(httpSessionEvent.session.id) } HttpSession getSessionById(id) { sessions.get(id) }}在 grails-app/conf/resoures.groovy 中注册import com.session.SessionTracker// Place your Spring DSL code herebeans = { // 自定义session监听器 sessionTracker(SessionTracker)}获取sessionpackage com.geneeimport org.springframework.web.context.request.RequestContextHolderimport javax.servlet.http.HttpSessionclass HiController { // 注入监听对象 def sessionTracker def index() { // 获取session def sessionId = RequestContextHolder.currentRequestAttributes().getSessionId() println “原sessionId:$sessionId” // 根据sessionId获取session对象 HttpSession httpSession = sessionTracker.getSessionById(sessionId).getId() println “获取到session后:"+httpSession.getId() // 使session立即失效 sessionTracker.getSessionById(sessionId).invalidate() render sessionId }} ...

February 22, 2019 · 1 min · jiezi

Grails集成Quartz插件实现定时任务(Job)

build.gradle依赖://定时器compile ‘org.grails.plugins:quartz:2.0.0.M4’创建一个job,执行命令:create-job com.test.Test修改TestJob:package com.testclass TestJob {static triggers = {} def execute(context) { // execute job println “执行…” // 获取传递过来的参数 def msg = context.mergedJobDataMap.get(“tip”) println msg }}控制器中动态调用:def personPush() { println “xxxxx” // 传参到job中 TestJob.schedule(new Date(),[tip: “执行了定时器。。。”])}暂停定时任务def jobManagerServicedef index() { // 停止所有定时任务 jobManagerService.pauseAll() render “Stop all Job."}恢复定时任务jobManagerService.resumeAll()JobManagerService服务中常用方法Map <String , List<JobDescriptor>> getAllJobs() {}List<JobDescriptor> getJobs(String group) {}def getRunningJobs() {}def pauseJob(String group, String name) {}def resumeJob(String group, String name) {}def pauseTrigger(String group, String name) {}def resumeTrigger(String group, String name) {}def pauseTriggerGroup(String group) {}def resumeTriggerGroup(String group) {}def pauseJobGroup(String group) {}def resumeJobGroup(String group) {}def pauseAll() {}def resumeAll() {}def removeJob(String group, String name) {}def unscheduleJob(String group, String name) {}def interruptJob(String group, String name) {}可自行查看grails.plugins.quartz.JobManagerService类常用方法:MyJob.schedule(String cronExpression, Map params) // 创建cron触发器MyJob.schedule(Long repeatInterval, Integer repeatCount, Map params) // 创建简单的触发器:以repeatInterval毫秒的延迟重复作业repeatCount + 1次MyJob.schedule(Date scheduleDate, Map params) // 将一个作业执行安排到特定日期MyJob.schedule(Trigger trigger) // 使用自定义触发器来安排作业的执行MyJob.triggerNow(Map params) // 强制立即执行工作 ...

January 18, 2019 · 1 min · jiezi