Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4j write spring-security username

I am using log4j and spring-security in application, and the logger should write logs with username in every message. I am very new to all of this, can somebody help with advice or links? Maybe there is some standart ways of solving this? Thank you.

EDIT Using spring framework 3.1 My spring-security.xml is:

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <http pattern="/favicon.ico" security="none" />
    <http auto-config="true">
            <intercept-url pattern="/**" access="ROLE_ADMIN"/>
    </http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="detect_me" password="1111" authorities="ROLE_ADMIN" />
        </user-service>
    </authentication-provider>
</authentication-manager>

And log4j.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>    
    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %p [%c] - %m%n" />
        </layout>
    </appender>
    <appender name="R" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="/logs/urlbuilderweb.log"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %p %t %c - %m%n" />            
        </layout>
    </appender>
    <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="10000"/>
        <appender-ref ref="R"/>
    </appender>
    <logger name="org.springframework">
        <level value="WARN"/>
    </logger>
    <logger name="org.directwebremoting">
        <level value="WARN"/>
    </logger>
    <logger name="org.apache.http">
        <level value="WARN"/>
    </logger>
    <logger name="org.hibernate">
        <level value="WARN"/>
    </logger>
    <root>
        <level value="INFO" />
        <appender-ref ref="ASYNC"/>
    </root>
</log4j:configuration>
like image 941
me1111 Avatar asked Dec 18 '12 08:12

me1111


1 Answers

You can use NDC feature. Set up some filter / interceptor (depends on what presentation technology you use). Add nested diagnostic context (filter example):

public class LogDiagnosticContextFilter implements javax.servlet.Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // do nothing
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
        ServletException {
        SecurityContext context = SecurityContextHolder.getContext();
        if (context != null) {
            Authentication authentication = context.getAuthentication();
            if (authentication != null) {
                NDC.push("Username=" + authentication.getName());
            }
        }
        chain.doFilter(request, response);
        NDC.pop();
    }
    @Override
    public void destroy() {
        // do nothing
    }
}

Ensure that filter executed after Spring Security filter chain (web.xml):

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>logDiagnosticContextFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>   

Add x to each interested log4j pattern:

%x %d %p %t %c - %m%n

Later when you call

LOGGER.info("some text");

anywhere in you code you will see

Username=corresponding_login some text

in your log

like image 58
Maksym Demidas Avatar answered Sep 29 '22 12:09

Maksym Demidas