想在用户登录时,不管成功还是失败,写个日志。
别的都好说,就是这个ip,愁死我了。
我是在QueryDatabaseAuthenticationHandler这个类里修改,
它的代码在
cas-server-3.5.2-release.jar的 \cas-server-3.5.2\cas-server-support-jdbc\src\main\java\org\jasig\cas\adaptors\jdbc 下面。
原始内容:
/* * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at the following location: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.cas.adaptors.jdbc;
import org.jasig.cas.authentication.handler.AuthenticationException; import org.jasig.cas.authentication.principal.UsernamePasswordCredentials; import org.springframework.dao.IncorrectResultSizeDataAccessException;
import javax.validation.constraints.NotNull;
/** * Class that if provided a query that returns a password (parameter of query * must be username) will compare that password to a translated version of the * password provided by the user. If they match, then authentication succeeds. * Default password translator is plaintext translator. * * @author Scott Battaglia * @author Dmitriy Kopylenko * @version $Revision$ $Date$ * @since 3.0 */ public class QueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
@NotNull private String sql;
protected final boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials) throws AuthenticationException { final String username = getPrincipalNameTransformer().transform(credentials.getUsername()); final String password = credentials.getPassword(); final String encryptedPassword = this.getPasswordEncoder().encode( password); try { final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username); return dbPassword.equals(encryptedPassword); } catch (final IncorrectResultSizeDataAccessException e) { // this means the username was not found. return false; } }
/** * @param sql The sql to set. */ public void setSql(final String sql) { this.sql = sql; } }
可以看到,比较简单,就是执行sql,然后比较密码。
闲言碎语不多讲,直接贴修改后代码:
/* * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at the following location: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.cas.adaptors.jdbc;
import java.util.Date;
import org.jasig.cas.authentication.handler.AuthenticationException; import org.jasig.cas.authentication.principal.UsernamePasswordCredentials; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.web.context.request.RequestContextHolder;
import com.github.inspektr.common.web.ClientInfoHolder;
import javax.validation.constraints.NotNull;
/** * Class that if provided a query that returns a password (parameter of query * must be username) will compare that password to a translated version of the * password provided by the user. If they match, then authentication succeeds. * Default password translator is plaintext translator. * * @author Scott Battaglia * @author Dmitriy Kopylenko * @version $Revision$ $Date$ * @since 3.0 */ public class QueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
@NotNull private String sql;
protected final boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials) throws AuthenticationException { final String username = getPrincipalNameTransformer().transform(credentials.getUsername()); final String password = credentials.getPassword(); final String encryptedPassword = this.getPasswordEncoder().encode( password); //插入日志的sql String sql = "insert into event_log(event_time,system_name,username,ip,action_type,action_detail,action_result) "+ "values(?,?,?,?,?,?,?)"; String ip = ClientInfoHolder.getClientInfo().getClientIpAddress(); try { final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username); if(dbPassword.equals(encryptedPassword)){ //登录成功 getJdbcTemplate().update(sql, new Object[]{new Date(),"单点登录",username,ip,"登录系统","用户名+密码登录系统","登录成功。"}); return true; } //密码不正确,登录失败 getJdbcTemplate().update(sql, new Object[]{new Date(),"单点登录",username,ip,"登录系统","用户名+密码登录系统","登录失败,密码错误。"}); return false; } catch (final IncorrectResultSizeDataAccessException e) { RequestContextHolder.getRequestAttributes().getAttribute("aa", 1); //用户不存在 getJdbcTemplate().update(sql, new Object[]{new Date(),"单点登录",username,ip,"登录系统","用户名+密码登录系统","登录失败,用户名不存在。"}); return false; } }
/** * @param sql The sql to set. */ public void setSql(final String sql) { this.sql = sql; } }
IP是这样取得的: String ip = ClientInfoHolder.getClientInfo().getClientIpAddress();
我去,超级简单哈~~ 害我找了N久,搜也搜不到~~
后来看到web.xml中有:
<filter> <filter-name>CAS Client Info Logging Filter</filter-name> <filter-class>com.github.inspektr.common.web.ClientInfoThreadLocalFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Client Info Logging Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
看到client info字样,而且之前看过,inspektr好像是个监控意思的类
搜ClientInfoThreadLocalFilter代码,果然有收获:
package com.github.inspektr.common.web;
import java.io.IOException;
import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest;
public final class More ...ClientInfoThreadLocalFilter implements Filter {
public void More ...destroy() { // nothing to do here } public void More ...doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain) throws IOException, ServletException { try { final ClientInfo clientInfo = new ClientInfo((HttpServletRequest) request); ClientInfoHolder.setClientInfo(clientInfo); filterChain.doFilter(request, response); } finally { ClientInfoHolder.clear(); } }
public void More ...init(final FilterConfig filterConfig) throws ServletException { // nothing to do } }
它把request对象封成了ClientInfo对象,扔到了ClientInfoHolder里。
以下是ClientInfoHolder的代码 :
package com.github.inspektr.common.web;
public final class ClientInfoHolder { private static final ThreadLocal<ClientInfo> clientInfoHolder = new ThreadLocal<ClientInfo>(); public static void setClientInfo(final ClientInfo clientInfo) { clientInfoHolder.set(clientInfo); } public static ClientInfo getClientInfo() { return clientInfoHolder.get(); } public static void clear() { clientInfoHolder.remove(); } }
里面用ThreadLocal来存储clientInfo, 也就是说,每个请求的线程自己保存clientInfo,这样每个人的信息就分开了。
哈哈,好简单,好NB~~
所以咱们在随便哪个类里直接 ClientInfoHolder.getClientInfo()就得到了ClientInfo,
里面就是ClientIP和ServerIP,没别的,呵呵。
|