一、搭建cas服務器
1.下載cas-overlay-template,這裏用的是5.2版本,github地址爲:
https://github.com/apereo/cas-overlay-template/tree/5.2
2.用Intellji Idea打開項目,然後添加當前項目爲maven項目。執行Maven命令mvn install。執行時間較長,需耐心等待。執行結束後,該項目中會出現overlays目錄,裏面就是cas server的配置文件和class代碼。
3.mvn install執行後會在項目的target目錄下生成一個cas.war包,將該war包放在apache tomcat的webapps/目錄下並啓動tomcat後,就能通過瀏覽器訪問,訪問地址 localhost:8080/cas。默認的登錄用戶名和密碼(默認爲casuser/Mellon)
4.重點-修改默認的登錄方式,自定義登錄頁、退出跳轉頁、添加登錄加解密校驗、添加驗證碼等。
4.1 在項目中添加src/main/java和src/main/resources目錄,並將src/main/java設置爲代碼文件根目錄,將src/main/resources設置爲資源文件根目錄。目錄結構如下:
5.在overlay裏面找到casLoginView.html和casLogoutView.html,複製到resource/template目錄下,表單裏面內容及提交方式不變,修改樣式爲我們自定義的樣式,樣式文件可放在自己定義的resource/static目錄下。並在表單中添加驗證碼。
casLoginView:
<!DOCTYPE html>
<!--
~ 版權所有.(c)2008-2017.卡爾科技工作室
-->
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title th:text="${#themes.code('cas.pageTitle')}"></title>
<title>登錄</title>
<link rel="stylesheet"th:href="@{${#themes.code('base.css.file')}}"/>
<link rel="stylesheet"th:href="@{${#themes.code('login.css.file')}}"/>
<script th:src="@{${#themes.code('captcha-mini.js.file')}}"></script>
<script th:src="@{${#themes.code('jquery.min.js.file')}}"></script>
<script th:src="@{${#themes.code('layer.min.js.file')}}"></script>
<script th:inline="javascript">
var ctx = /*[[@{/}]]*/'';
ctx = ctx.substr(0, ctx.length - 1)
</script>
</head>
<body class="login_body">
<div class="lgoin_tit">
<h1>登錄頁</h1>
</div>
<div class="login_main fadeInRight">
<form method="post" id="fm1" th:object="${credential}" action="login">
<div class="alert alert-danger" th:if="${#fields.hasErrors('*')}">
<span th:each="err : ${#fields.errors('*')}" th:utext="${err}"/>
</div>
<label class="login_label">
<span class="login_span_text">賬號:</span>
<input class="required inp_login" id="username" size="25" tabindex="1" type="text" th:disabled="${guaEnabled}"
th:field="*{username}"
th:accesskey="#{screen.welcome.label.netid.accesskey}"
autocomplete="off"/>
</label>
<label class="login_label">
<span class="login_span_text">密碼:</span>
<input class="required inp_login" type="password" id="password" size="25" tabindex="2" th:accesskey="#{screen.welcome.label.password.accesskey}" th:field="*{password}"
autocomplete="off"/>
</label>
<label class="login_label">
<span class="login_span_text">驗證碼:</span>
<input class="required inp_login" style="width: 44%"
id="capcha"
name="capcha"
size="25"
tabindex="3"
th:field="*{capcha}"
autocomplete="off" placeholder="請輸入驗證碼"/>
<span class="login_span_img">
<img th:src="@{/capcha}" style="width: 160px;height:40px;" id="capchaImg">
</span>
</label>
<a href="javascript:void(0)" onclick="submit()" class="but_login mT20">登錄</a>
<input type="hidden" name="execution" th:value="${flowExecutionKey}"/>
<input type="hidden" name="_eventId" value="submit"/>
<input type="hidden" name="geolocation"/>
<input class="btn btn-submit btn-block"
name="submit"
accesskey="l"
value="登錄"
tabindex="6"
type="submit"
style="display: none"
id="login"/>
</form>
</div>
<script>
function submit() {
var username = $("#username").val().trim();
if (username == null || username == "") {
layer.tips('請輸入賬號', '#username');
return;
}
var password = $("#password").val().trim();
if (password == null || password == "") {
layer.tips('請輸入密碼', '#password');
return;
}
var code = $("#capcha").val().trim();
if (code == null || code == "") {
layer.tips('請輸入驗證碼', '#capcha');
return;
}
// 校驗通過後登陸後臺
$("#login").trigger('click',true);
// $("#fm1").submit();
}
</script>
<script type="text/javascript" th:inline="javascript">
var i = [[#{screen.welcome.button.loginwip}]]
$("#fm1").submit(function () {
$(":submit").attr("disabled", true);
$(":submit").attr("value", i);
return true;
});
$("#capchaImg").click(function () {
$("#capchaImg").attr("src",ctx+"/capcha");
})
</script>
</body>
</html>
casLogoutView.html:
<!DOCTYPE html>
<html>
<head>
<title th:text="#{screen.logout.header}"></title>
<!-- 以下方式轉到統一身份認證登錄頁面 -->
<!-- <meta http-equiv="refresh" content="0;url=/cas/login">-->
</head>
<script language="javascript" type="text/javascript">
window.onload=function(){//用window的onload事件,窗體加載完畢的時候
let example = window.location.search;
console.log(example);
if(example.indexOf("ebc") != -1){
window.location.href="";
}
else if(example.indexOf("building") != -1){
window.location.href="";
}
}
</script>
</html>
引入的樣式文件:cas-theme-default.properties
standard.custom.css.file=/css/cas.css
admin.custom.css.file=/css/admin.css
cas.javascript.file=/js/cas.js
cas.css.file=/themes/cas/css/cas.css
awesome.css.file=/themes/cas/css/awesome.css
bootstrap.min.css.file=/themes/cas/css/bootstrap.min.css
animate.css.file=/themes/cas/css/animate.css
#login.css.file=/themes/cas/css/login.css
style.css.file=/themes/cas/css/style.css
cas.pageTitle=ARM\u7EDF\u4E00\u8EAB\u4EFD\u8BA4\u8BC1\u5E73\u53F0
base.css.file=/themes/cas/css/base.css
login.css.file=/themes/cas/css/login.css
captcha-mini.js.file=/themes/cas/js/captcha-mini.js
jquery.min.js.file=/themes/cas/js/jquery.min.js
layer.min.js.file=/themes/cas/js/layer/layer.min.js
6.添加自定義接收登錄的參數及驗證碼校驗等
LoginUtil:
package com.jxbd.cas;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.HandlerResult;
import org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler;
import org.apereo.cas.authentication.PreventedException;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;
public class LoginUtil extends AbstractPreAndPostProcessingAuthenticationHandler {
public LoginUtil(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {
super(name, servicesManager, principalFactory, order);
}
@Override
protected HandlerResult doAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {
UsernamePasswordCaptchaCredential mycredential1 = (UsernamePasswordCaptchaCredential) credential;
String capcha = mycredential1.getCapcha().toLowerCase();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String right = attributes.getRequest().getSession().getAttribute("capcha").toString().toLowerCase();
if(!capcha.equals(right)){
throw new FailedLoginException("驗證碼錯誤");
}
DriverManagerDataSource d = new DriverManagerDataSource();
d.setDriverClassName("com.mysql.jdbc.Driver");
d.setUrl("jdbc:mysql://");
d.setUsername("");
d.setPassword("");
JdbcTemplate template = new JdbcTemplate();
template.setDataSource(d);
String username=mycredential1.getUsername();
//查詢數據庫加密的的密碼
Map<String,Object> user = template.queryForMap("SELECT password FROM sys_user WHERE username = ?", mycredential1.getUsername());
System.out.println("密碼"+user.get("password"));
if(user==null){
throw new FailedLoginException("沒有該用戶");
}
//返回多屬性(暫時不知道怎麼用,沒研究)
Map<String, Object> map=new HashMap<>();
map.put("email", "[email protected]");
MyPasswordEncoder encoder = new MyPasswordEncoder();
if(encoder.matches(mycredential1.getPassword(),user.get("password").toString())){
return createHandlerResult(mycredential1, principalFactory.createPrincipal(username, map), null);
}
throw new FailedLoginException("Sorry, login attemp failed.");
}
@Override
public boolean supports(Credential credential) {
return credential instanceof UsernamePasswordCaptchaCredential;
}
}
未完待續。。。