com.k2.shiro.Shiro Maven / Gradle / Ivy
The newest version!
/* vim: set et ts=2 sw=2 cindent fo=qroca: */
package com.k2.shiro;
import java.util.Map;
import java.util.LinkedHashMap;
import javax.servlet.Filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import com.k2.core.ModuleDefinition;
import com.k2.core.RegistryFactory;
/** This module integrates shiro in k2 applications.
*
* To use this module you need to create a module that provides the login url
* (see ShiroRegistry) and a public bean that implements a shiro realm, or
* provide your realm implementation in your application.
*
* This module maintains all session information in a browser cookie, so do not
* abuse session information.
*
* It exposes a /logout endponint that mainly deletes the session cookie.
*/
@Component("shiro")
public class Shiro implements RegistryFactory {
/** The class logger. */
private final Logger log = LoggerFactory.getLogger(Shiro.class);
/** The login url registered by at most one module.
*
* Null if there is no login form configured in the application.
*/
private String loginUrl = null;
/** The shiro filter chain definition, a map of url patters to filters to
* apply to that url.
*
* This is written by the ShiroRegistry when a module calls registerEndpoint.
*/
private final Map chainDefinitions = new LinkedHashMap<>();
/** Registers the shiro login page.
*
* @param url the context relative url that will provide the login page. It
* cannot be null.
*/
void registerLoginUrl(final String url) {
Validate.isTrue(loginUrl == null,
"Only one module can register the login url.");
loginUrl = url;
}
/** Adds a new chain definition to the list of shiro chain definitions.
*
* See ShiroRegistry.registerEndpoint for more information.
*
* @param pattern the url pattern. It cannot be null.
*
* @param chain the shiro filter chain. It cannot be null.
*/
void addChainDefinition(final String pattern, final String chain) {
if (chainDefinitions.isEmpty()) {
chainDefinitions.put("/logout", "saveSession, noSessionCreation, logout");
}
chainDefinitions.put(pattern, "saveSession, noSessionCreation, " + chain);
}
/** Creates a shiro registry for the provided module. */
@Override
public ShiroRegistry getRegistry(final ModuleDefinition requestor) {
log.trace("Entering getRegistry({})", requestor.getModuleName());
ShiroRegistry result;
result = new ShiroRegistry(requestor.getModuleName(), this);
log.trace("Leaving getRegistry()");
return result;
}
/** The security manager.
*
* @param cipher the cipher to use to encrypt and decrypt session cookies.
*
* @param realm the realm used by the security manager. This in intended to
* be configured in the K2 application as a spring bean. The name is
* irrelevant, it will be matched by type. It cannot be null.
*
* @return the security manager, never null.
*/
@Bean public SecurityManager securityManager(final K2Cipher cipher,
final Realm realm) {
Validate.notNull(realm,
"The realm cannot be null. Create one in your application.");
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
securityManager.setSubjectFactory(new K2SubjectFactory());
securityManager.setSessionManager(new K2SessionManager(cipher));
return securityManager;
}
/** Creates the main shiro filter that intercepts every call to the web
* application.
*
* @param securityManager the shiro security manager to use in this shiro
* filter. It cannot be null.
*
* @return a properly initialized shiro filter, set up to filter all
* requests. Never returns null.
*/
@Bean public FilterRegistrationBean shiroFilter(
final SecurityManager securityManager) {
ShiroFilterFactoryBean filterFactory = new ShiroFilterFactoryBean();
filterFactory.setSecurityManager(securityManager);
filterFactory.getFilters().put("saveSession", new SaveSessionFilter());
addChainDefinition("/**", "authc");
filterFactory.setFilterChainDefinitionMap(chainDefinitions);
filterFactory.setLoginUrl(loginUrl);
Filter filter;
try {
filter = (Filter) filterFactory.getObject();
} catch (Exception e) {
throw new RuntimeException("Error creating shiro filter.", e);
}
FilterRegistrationBean registration;
registration = new FilterRegistrationBean<>(filter);
registration.setName("shiroFilter");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
return registration;
}
/** Creates the cipher to encrypt and decrypt shiro session cookies.
*
* @param password the password to use. It cannot be null.
*
* @return cipher, never returns null.
*/
@Bean public K2Cipher cipher(
@Value("${shiro.password:}") final String password) {
Validate.notBlank(password,
"You must define a property shiro.password with the session password.");
return new K2Cipher(password);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy