本文主要讲解的是jhipster与cas的整合,目前这一方面国内的资料少之甚少,笔者在踩过无数次坑,填无数次坑后决定将这一方面的技术记录下来,分享给大家。阅读本文,同时有过jhipster和cas使用经验的人理解起来比较容易,您可以略过介绍jhipster和cas配置的部分,直接看jhipster与cas的整合部分。
废话不多说,让我们进入主题。
jhipster是一个开发平台,用于开发和部署基于spring-boot启动的angularjs web应用程序,通俗的讲,他最大的特点就是应用程序的所有前端+后端代码都是自动生成的,并且所用数据库、框架、技术栈可以根据需要在生成时随意选择。
jhipster所需环境:
1.jdk8
2. Maven 或 Gradle
3.Git
4.Node.js
jhipster安装步骤:
1.安装npm : npm install -g npm
2.安装Yeoman : npm install -g yo
3.安装bower(适用于生成angularjs 1 应用):npm install -g bower
4.安装Gulp(适用于生成angularjs 1 应用) :npm install -g gulp-cli
5.安装jhipster :npm install -g generator-jhipster
6.(可选项)安装yarn: npm install -g yarn
以上内容来自jhipster官网,如需更详细,请仔细阅读官网内容:http://www.jhipster.tech/installation/
jhipster环境安装完毕,接下来我们生成一个jhipster项目
1.打开任意一个文件夹,shift+鼠标右键打开控制台输入 yo jhipster 如图所示:
接下来的问题回答,依次如图所示:
问题4为选择用户认证技术,问题11为选择开源技术,问题12为选择前端框架
如需详细解释请参考官网:http://www.jhipster.tech/creating-an-app/
回答完问题之后npm会自动下载jhipster所需的组件 (有些组件如果下载不下来,请使用你(翻)懂(蔷)得)
接下来我们需要修改jhipster的数据源,打开jhipster项目 src\main\resources\config下的application-dev.yml文件,修改数据源如下文所示(mysql数据库):
spring:
profiles:
active: dev
include: swagger
devtools:
restart:
enabled: true
livereload:
enabled: false # we use gulp + BrowserSync for livereload
jackson:
serialization.indent_output: true
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://localhost:3306/kettle?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: root
修改完数据源后,在项目根目录打开控制台依次运行bower install ,gulp install 待成功之后运行mvn spring-boot:run或点击根目录的mvnn.cmd文件启动jhipster,启动成功入下图所示:
在浏览器运行localhost:(端口号) ,成功如下图所示:
好了,关于jhipster的配置与安装就介绍到这里,jhipster生成实体部分不在这里讲解,详细请参考官网文档http://www.jhipster.tech/creating-an-entity/
接下来讲解CAS服务端的搭建与部署,网上这方面的文章有很多,方法不统一,我的方法仅供大家参考。
大致总结一下本地配置CAS服务端的几个步骤,如下:
1.在hosts中配置域名
2. 用jdk中的 java tool生成cas所需秘钥
3.下载cas服务端jar包
4.配置cas服务端tomcat的server.xml
1.打开本地hosts配置3个可用域名
127.0.0.1 demo.kettle.com (cas服务端域名)
127.0.0.1 app1.kettle.com (cas客户端域名)
127.0.0.1 app2.kettle.com (cas客户端域名)
2. 用jdk中的 java tool生成cas所需秘钥
创建证书(这里的keypassword与keystorepassword都为kettle):
使用java keytool证书工具 :找到系统jdk所在的位置,进入bin目录运行,打开命令行运行:
keytool -genkey -alias kettle -keyalg RSA -keysize 1024 -keypass kettle -validity 365 -keystore F:\keys\kettle\kettle.keystore -storepass kettle
导出证书:
keytool -export -alias kettle -keystore F:\keys\kettle\kettle.keystore -file F:\keys\kettle.crt -storepass kettle
把证书导入到客户端JDK中(win7要使用 ctrl+shift+enter打开cmd获取系统管理员权限):
keytool -import -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -file F:\keys\kettle.crt -alias kettle
密码输入:changeit
3.下载cas服务端jar包:
下载 cas-server-web-4.0.0.zip 解压后 到modules文件夹中找到cas-management-webapp-4.0.0.war
将cas-server-webapp-4.0.0.war改名为cas.war拷贝到tomcat目录的webapps文件夹中
修改tomcat文件夹下的conf/server.xml文件,使其支持https:
4.配置cas服务端tomcat的server.xml
修改8080端口的内容使其指向8443:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
去掉下面8443端口的注释,加入证书信息
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="F:\keys\kettle\kettle.keystore"
keystorePass="kettle"
truststoreFile="C:\Program Files\Java\jdk8\jre\lib\security\cacerts"
/>
去tomcat目录下的bin文件夹点击startup.bat启动tomcat,浏览器输入https://demo.kettle.com:8443/cas 点击继续前往
进入cas认证中心 如下图所示:
初始用户名为casuser密码Mellon 登录成功如下图所示,表示配置成功, 如果启动失败 请检查证书是否生成正确
目前为止,jhipster的配置与cas的配置已经讲解完毕,下面我们着手解决jhipster与cas的集成问题,由于修改的文件比较多,查看源码请到如下地址下载:https://pan.baidu.com/s/1hrSa3ZI jhipster.src.main.rar
1.修改核心配置文件SecurityConfiguration.java ,位置如下:
2.在config目录加入CasProperties和JhipsterProperties并替换掉原来io.github.jhipster包中的casProperties和jhipsterProperties,替换后的config目录如下:
3.在web目录下加入SimpleController文件,作为cas登录的入口
4.在security下加入cas文件夹,加入如下文件:
CustomSessionFixationProtectionStrategy
CustomSingleSignOutFilter
CustomSingleSignOutHandler
RememberCasAuthenticationEntryPoint
RememberCasAuthenticationProvider
RememberWebAuthenticationDetails
RememberWebAuthenticationDetailsSource
同时修改security文件夹下的:
AjaxAuthenticationFailureHandler
AjaxAuthenticationSuccessHandler
AjaxLogoutSuccessHandler
修改security文件夹下的DomainUserDetailsService文件名为UserDetailsService同时修改其中的内容:
DomainUserDetailsService
修改后的目录结构如下图所示:
5.修改service/dto文件夹下的UserDTO
6.修改webapp/app/components/login下的 login.controller.js和login.service.js使之适应cas
7.修改webapp/app/service/auth的 auth.service.js和auth.session.service.js使之适应cas
8.修改src/main/resources/config下的application-dev.yml,设置jhipster的SSL
代码如下:
# ===================================================================
# Spring Boot configuration for the "dev" profile.
#
# This configuration overrides the application.yml file.
#
# More information on profiles: https://jhipster.github.io/profiles/
# More information on configuration properties: https://jhipster.github.io/common-application-properties/
# ===================================================================
# ===================================================================
# Standard Spring Boot properties.
# Full reference is available at:
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
# ===================================================================
spring:
profiles:
active: dev
include: swagger
devtools:
restart:
enabled: true
livereload:
enabled: false # we use gulp + BrowserSync for livereload
jackson:
serialization.indent_output: true
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://localhost:3306/kettle?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: root
h2:
console:
enabled: false
jpa:
database-platform: io.github.jhipster.domain.util.FixedH2Dialect
database: H2
show-sql: true
properties:
hibernate.id.new_generator_mappings: true
hibernate.cache.use_second_level_cache: true
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: true
hibernate.cache.region.factory_class: io.github.jhipster.config.jcache.NoDefaultJCacheRegionFactory
data:
elasticsearch:
cluster-name:
cluster-nodes:
properties:
path:
logs: target/elasticsearch/log
data: target/elasticsearch/data
mail:
host: localhost
port: 25
username:
password:
messages:
cache-seconds: 1
thymeleaf:
cache: false
liquibase:
contexts: dev
# ===================================================================
# To enable SSL, generate a certificate using:
# keytool -genkey -alias ausp -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
#
# You can also use Let's Encrypt:
# https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm
#
# Then, modify the server.ssl properties so your "server" configuration looks like:
#
# server:
# port: 8443
# ssl:
# key-store: keystore.p12
# key-store-password: <your-password>
# keyStoreType: PKCS12
# keyAlias: ausp
# ===================================================================
server:
port: 18080
address: app1.kettle.com
ssl:
key-store: F:/keys/kettle/kettle.keystore
key-alias: kettle
key-password: kettle
key-store-password: kettle
enabled: true
# ===================================================================
# JHipster specific properties
#
# Full reference is available at: https://jhipster.github.io/common-application-properties/
# ===================================================================
jhipster:
http:
version: V_1_1 # To use HTTP/2 you will need SSL support (see above the "server.ssl" configuration)
cache: # Cache configuration
ehcache: # Ehcache configuration
time-to-live-seconds: 3600 # By default objects stay 1 hour in the cache
max-entries: 100 # Number of objects in each cache entry
# CORS is only enabled by default with the "dev" profile, so BrowserSync can access the API
cors:
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
security:
remember-me:
# security key (this key should be unique for your application, and kept secret)
key: f8df3decb4f433f9d3b0491343f26812619667b7
mail: # specific JHipster mail property, for standard properties see MailProperties
from: ausp@localhost
base-url: http://127.0.0.1:8080
metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
jmx.enabled: true
graphite: # Use the "graphite" Maven profile to have the Graphite dependencies
enabled: false
host: localhost
port: 2003
prefix: ausp
prometheus: # Use the "prometheus" Maven profile to have the Prometheus dependencies
enabled: false
endpoint: /prometheusMetrics
logs: # Reports Dropwizard metrics in the logs
enabled: false
report-frequency: 60 # in seconds
logging:
logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
enabled: false
host: localhost
port: 5000
queue-size: 512
# ===================================================================
# Application specific properties
# Add your own application properties here, see the ApplicationProperties class
# to have type-safe configuration, like in the JHipsterProperties above
#
# More documentation is available at:
# https://jhipster.github.io/common-application-properties/
# ===================================================================
application:
# ===================================================================
# CAS Integration
# ===================================================================
cas:
service:
security: https://app1.kettle.com:18080/login/cas
home: https://app1.kettle.com:18080/
url:
prefix: https://demo.kettle.com:8443/cas/
login: https://demo.kettle.com:8443/cas/login
logout: https://demo.kettle.com:8443/cas/logout
最后到cas服务端(最开始配置tomcat承载的那个)找到webapps/cas/WEB-INF/ 下的deployerConfigContext.xml并修改,使之连接jhipster数据库
注释掉primaryAuthenticationHandler,并加入dbAuthHandler,代码如下:
注:这里屏蔽了密码加密方式,测试时请在数据中手动加入一个明文账号进行测试!
<constructor-arg>
<map>
<!--
| IMPORTANT
| Every handler requires a unique name.
| If more than one instance of the same handler class is configured, you must explicitly
| set its name to something other than its default name (typically the simple class name).
-->
<entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
<entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver"/>
<!-- <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" /> -->
</map>
</constructor-arg>
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
p:driverClass="com.mysql.jdbc.Driver" p:jdbcUrl="jdbc:mysql://localhost:3306/kettle?useUnicode=true&characterEncoding=utf8&noAccessToProcedureBodies=true&autoReconnect=true&zeroDateTimeBehavior=convertToNull"
p:user="root"
p:password="root" />
<!-- 密码加密方式-->
<!-- <bean id="passwordEncoder" -->
<!-- class="com.my.cas.authentication.handler.SelfPasswordEncoder" -->
<!-- c:encodingAlgorithm="SHA1" -->
<!-- p:characterEncoding="UTF-8" /> -->
<!-- <bean id="dbAuthHandler" -->
<!-- class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler" -->
<!-- p:dataSource-ref="dataSource" -->
<!-- p:sql="select password_hash from jhi_user where login=? " -->
<!-- p:passwordEncoder-ref="passwordEncoder" -->
<!-- /> -->
<bean id="dbAuthHandler"
class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"
p:dataSource-ref="dataSource"
p:sql="select password_hash from jhi_user where login=? "
/>