Apache Shiro authentication using encrypted data - shiro

I'm able to Authenticate user using Apache Shiro by passing username and password. But if i have pass encrypted data, then how will i achieve this?
I have tried the below:
public static void main(String[] args) {
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
JcaCipherService jcaCipherService =new DefaultBlockCipherService("RSA") ;
jcaCipherService.decrypt("UOK4yfsmoavRDq+5NiYuMh2s2KC9GBzUCra4MGIx+7ERbdb0IRGsQZxDza7kir/OAupq18Vzm8cZzaHoKeC/TA==".getBytes(), "MIIBVwIBADANBgkqhk".getBytes());
But is it giving me the below error:
Exception in thread "main" org.apache.shiro.crypto.CryptoException: Unable to acquire a Java JCA Cipher instance using javax.crypto.Cipher.getInstance( "RSA/CBC/PKCS5Padding" ). RSA under this configuration is required for the org.apache.shiro.crypto.DefaultBlockCipherService instance to function.
at org.apache.shiro.crypto.JcaCipherService.newCipherInstance(JcaCipherService.java:414)
at org.apache.shiro.crypto.JcaCipherService.initNewCipher(JcaCipherService.java:591)
at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:444)
at org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:390)
at org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:382)
at com.thbs.esb.authenticate.Authenticate.main(Authenticate.java:24)
Caused by: java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/CBC/PKCS5Padding
at javax.crypto.Cipher.getInstance(Cipher.java:539)
at org.apache.shiro.crypto.JcaCipherService.newCipherInstance(JcaCipherService.java:408)
... 5 more

Related

spring-mail-starter ignoring spring.mail.* config

I have a project using spring-boot and added
the following dependency in my build.gradle:
compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '1.5.7.RELEASE'
My application.properties contains
SMTP Configuration
spring.mail.host=mail.xxx
spring.mail.port=587
spring.mail.username=donotreply#xxx
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.from=donotreply#xxx
According to multiple answers here and documentations i found,that should be enought to create the bean with this settings.
I now want to use a mailer in a Service class
#Autowired
private JavaMailSender emailSender;
[...]
#Value("${spring.mail.host}")
private String mailHost;
When i try to send a message using emailSender i get the following error:
Mail server connection failed; nested exception is
com.sun.mail.util.MailConnectException: Couldn't connect to host,
port: localhost, 25; timeout -1; nested exception is:
java.net.ConnectException: Connection refused: connect. Failed
messages: com.sun.mail.util.MailConnectException: Couldn't connect to
host, port: localhost, 25; timeout -1; nested exception is:
java.net.ConnectException: Connection refused: connect
Obviously it is trying to connect to localhost instead of the configured host.
The variable mailHost does contain the correct value, so the properties are read correct.
EDIT:
The autowired class for emailSender is org.springframework.mail.javamail.JavaMailSenderImpl, which seems to be correct to me.
In my case, the reason was that I instantiated the bean myself like this:
#Bean
public JavaMailSender mailSender() throws IOException {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setDefaultEncoding("UTF-8");
return mailSender;
}
Not sure why, but that way, it ignores the application.properties. Maybe the reason was, that I explicitly instantiated JavaMailSenderImpl to set a default encoding and possibly that implementation isn't application.properties aware?
However, removing that bean solved the problem.
[FOUND]
A co-worker was working on the same and had commited an incomplete bean definition. That bean was autowired.

JBOSS EAP 7 - EJB Client user data

I have migrated my EJB application from jboss 5.0.1 to JBOSS EAP 7.
I want to pass user data from EJB client to my EJB.
I'm using this code to pass custom attribute to ejb server but it does not work anymore.
Client:
public class CustomData extends SimplePrincipal{
String userData1;
public CustomData(String userData1){
this.userData1 = userData1;
}
SecurityClient client = SecurityClientFactory.getSecurityClient();
client.setSimple(new CustomData("MyData"), credentials.getPass());
client.login();
Server:
#Resource
SessionContext ejbCtx;
Principal data= ejbCtx.getCallerPrincipal();
data.getName() --- anonymous
How to fix it on new JBOSS ?
1.Create the client side interceptor
This interceptor must implement the org.jboss.ejb.client.EJBClientInterceptor. The interceptor is expected to pass the additional security token through the context data map, which can be obtained via a call to EJBClientInvocationContext.getContextData().
2.Create and configure the server side container interceptor
Container interceptor classes are simple Plain Old Java Objects (POJOs). They use the #javax.annotation.AroundInvoke to mark the method that is invoked during the invocation on the bean.
a.Create the container interceptor
This interceptor retrieves the security authentication token from the context and passes it to the JAAS (Java Authentication and Authorization Service) domain for verification
b. Configure the container interceptor
3.Create the JAAS LoginModule
This custom module performs the authentication using the existing authenticated connection information plus any additional security token.
Add the Custom LoginModule to the Chain
You must add the new custom LoginModule to the correct location the chain so that it is invoked in the correct order. In this example, the SaslPlusLoginModule must be chained before the LoginModule that loads the roles with the password-stacking option set.
a.Configure the LoginModule Order using the Management CLI
The following is an example of Management CLI commands that chain the custom SaslPlusLoginModule before the RealmDirect LoginModule that sets the password-stacking option.
b. Configure the LoginModule Order Manually
The following is an example of XML that configures the LoginModule order in the security subsystem of the server configuration file. The custom SaslPlusLoginModule must precede the RealmDirect LoginModule so that it can verify the remote user before the user roles are loaded and the password-stacking option is set.
Create the Remote Client
In the following code example, assume the additional-secret.properties file accessed by the JAAS LoginModule
See the link:
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.2/html/Development_Guide/Pass_Additional_Security_For_EJB_Authentication.html
I have done with this way:
Client:
Properties properties = new Properties();
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
properties.put("org.jboss.ejb.client.scoped.context", "true");
properties.put("remote.connection.default.username", "MyData");
Server:
public class MyContainerInterceptor{
#AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
Connection connection = RemotingContext.getConnection();
if (connection != null) {
for (Principal p : connection.getPrincipals()) {
if (p instanceof UserPrincipal) {
if (p.getName() != null && !p.getName().startsWith("$"))
System.out.println(p.getName()); //MyData will be printed
}
}
}
return ctx.proceed();
}
}
Don't forget to configure container interceptor in jboss-ejb3.xml (not in ejb-jar.xml)
<?xml version="1.0" encoding="UTF-8"?>
<jee:assembly-descriptor>
<ci:container-interceptors>
<jee:interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>package...MyContainerInterceptor</interceptor-class>
</jee:interceptor-binding>
</ci:container-interceptors>
</jee:assembly-descriptor>

How do I correctly register a custom FormAction in Keycloak?

Keycloak 1.9.1-Final
I've implemented the following custom FormActionFactory.
public class RegistrationFormActionFactory implements FormActionFactory{
public static final String PROVIDER_ID = "rc-registration-profile-action";
#Override
public FormAction create(KeycloakSession session){
return new RegistrationFormAction();
}
#Override
public String getDisplayType(){
return "RC Profile Validation";
}
...
And the associated FormAction modeled after org.keycloak.authentication.forms.RegistrationProfile
public class RegistrationFormAction implements FormAction{
...
in META-INF/services of the jar I have a file: org.keycloak.authentication.FormActionFactory
containing only the following text:
com.realcomp.keycloak.RegistrationFormActionFactory
Within the Keycloak admin pages, I have made a copy of the Registration authentication flow and named it Copy of Registration. When adding an execution to my new flow I see my custom "RC Profile Validation" FormAction on the drop-down list of available providers. When selected, I get the following exception in the Keycloak server logs:
14:31:00,264 ERROR [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-54) RESTEASY002005: Failed executing POST /admin/realms/master/authentication/flows/Copy of registration registration form/executions/execution: org.jboss.resteasy.spi.BadRequestException: No authentication provider found for id: rc-registration-profile-action
at org.keycloak.services.resources.admin.AuthenticationManagementResource.addExecution(AuthenticationManagementResource.java:394)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:139)
(omitted...)
Interesting side note: If I change the PROVIDER_ID in my FormActionFactory to "registration-profile-action" everything works as expected. However, this PROVIDER_ID is used by the RegistrationProfile class and feels wrong.
I increased logging verbosity and it appears my FormAction is being loaded:
17:07:20,659 DEBUG [org.keycloak.services] (ServerService Thread Pool -- 50) Loaded SPI form-action (providers = [registration-profile-action, rc-registration-profile-action, registration-recaptcha-action, registration-password-action, registration-user-creation])
I've likely missed some configuration step. Any ideas on what I did wrong here?
This is a bug that came on version 1.9.x.
An issue ticket has already been created, you can follow it here:
https://issues.jboss.org/browse/KEYCLOAK-2842

Storing Spring Boot users in a database with Grails 3.0

How do you store users in a database with a new plain vanilla Grails 3.0 application?
Background:
The Shiro and Spring Security plugins are not yet available for Grails 3.0 (and it sounds like Spring Boot is the future for Grails security).
There are various examples out there showing how to use inMemoryAuthentication(), but they seem completely pointless as passwords end up being stored in plain text (besides, it only takes about 30 seconds of effort to create a domain model in Grails).
Pretty much all Grails applications need this functionality.
I happen to be using MongoDB, but that's probably irrelevant.
Related: Grails 3 and Spring Security Plugin
I currently have inMemoryAuthentication() working with the following:
build.gradle
compile "org.springframework.boot:spring-boot-starter-security"
grails-app/conf/spring/resources.groovy
import com.tincanworks.AppSecurityConfig
beans = {
webSecurityConfiguration(AppSecurityConfig)
}
AppSecurityConfig.groovy
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
class AppSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/assets/**").permitAll()
.antMatchers("/admin/**").hasAnyRole("admin")
.anyRequest().authenticated()
.and()
.formLogin().permitAll()
.and()
.logout().permitAll()
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("123456").roles("user")
.and()
.withUser("admin").password("1qaz2wsx").roles("user", "admin")
}
}
It seems like the answer may be related to JdbcDaoImpl, but I have no idea how to hook that up in Grails.
GORM-based
I wrote up two blog posts (part 1 - In Memory Auth and part 2 - Gorm-based Auth) on how to use spring-starter-security and GORM in a Grails 3 application. I also created a github repo with a working Grails 3 application using spring-starter-security.
JDBC-based - untested
Alternatively, if you wanted to use the standard JDBC-based authentication you could just create the database tables using the following SQL script
HSQLDB
From http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-schema.html
create table users(
username varchar_ignorecase(50) not null primary key,
password varchar_ignorecase(50) not null,
enabled boolean not null);
create table authorities (
username varchar_ignorecase(50) not null,
authority varchar_ignorecase(50) not null,
constraint fk_authorities_users foreign key(username) references users(username));
create unique index ix_auth_username on authorities (username,authority);
MySQL
This comes from http://justinrodenbostel.com/2014/05/30/part-5-integrating-spring-security-with-spring-boot-web/
create table users (
username varchar(50) not null primary key,
password varchar(255) not null,
enabled boolean not null) engine = InnoDb;
create table authorities (
username varchar(50) not null,
authority varchar(50) not null,
foreign key (username) references users (username),
unique index authorities_idx_1 (username, authority)) engine = InnoDb;
and then change the configureGlobal method to
#Autowired //not sure if this is needed as you have the AppSecurityConfig bean referenced in resources.groovy
def datasource //bean injected by Grails
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.dataSource(datasource)
}
If you want to avoid building a whole User-management layer from scratch with a DB you could consider Stormpath.
Among other things, they provide a Spring Security Plugin that uses Stormpath as the authentication and authorization provider. They also have a sample Spring Security app that shows how the plugin is used. Since you are using Java Annotations (rather than xml configuration) take a look at this branch.
So, in summary, the key pieces that you will need to define are these:
The Stormpath Client Bean that will provide fast and secure communication with Stormpath via the Stormpath Java SDK:
//Let's create the Stormpath client using the apiKey.properties file from the User's home folder.
#Bean
ClientFactory stormpathClient(CacheManager cacheManager) {
ClientFactory clientFactory = new ClientFactory();
clientFactory.setApiKeyFileLocation(System.getProperty("user.home") + File.separator + ".stormpath" + File.separator + "apiKey.properties");
clientFactory.setCacheManager(cacheManager);
return clientFactory;
}
You will need to define the Stormpath Authentication Provider so Spring Security can transparently communicate with Stormpath to authenticate and authorize users:
#Bean
#Autowired
public StormpathAuthenticationProvider stormpathAuthenticationProvider(Client client, String applicationRestUrl) throws Exception {
StormpathAuthenticationProvider stormpathAuthenticationProvider = new StormpathAuthenticationProvider();
stormpathAuthenticationProvider.setClient(client);
stormpathAuthenticationProvider.setApplicationRestUrl(applicationRestUrl);
return stormpathAuthenticationProvider;
}
The applicationRestUrl needs to point to the Stormpath application where all the users/groups will exist:
#Bean
public String getApplicationRestUrl() {
return "https://api.stormpath.com/v1/applications/9TqbyZ2po73eDP4gYo2H92";
}
Your Spring Security configuration needs to be configured to use the Stormpath Authentication Provider:
//Let's add the StormpathAuthenticationProvider to the `AuthenticationProvider`
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(stormpathAuthenticationProvider);
}
Finally, in order to restrict the access to resources by roles, you will need to define the roles. For example:
//The access control settings are defined here
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.and()
.authorizeRequests()
.accessDecisionManager(accessDecisionManager())
.antMatchers("/account/*").hasAuthority("https://api.stormpath.com/v1/groups/36O9eBTN2oLtjoMSWLdnwL") //you are giving access to "/account/*" to users' that belong to the group univocally identified by this href value
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/index.jsp")
.and()
.httpBasic()
.and()
.csrf().disable();
}
Disclaimer, I am an active Stormpath contributor.

RMI using spring. Executing method in server with object as parameter

I am trying to execute a method from client to server using RMI.
As long as the parameters are String, it is getting executed correctly. If I am using object as method parameter.
I am getting following exception :
java.rmi.UnmarshalException: Error unmarshaling return; nested exception is:
java.lang.ClassNotFoundException: org.eclipse.persistence.exceptions.DatabaseException (no security manager: RMI class loader disabled)
Server configuration:
#Bean
public RmiServiceExporter getUserService() {
RmiServiceExporter exporter = new RmiServiceExporter();
exporter.setService(userService);
exporter.setServiceName("UserService");
exporter.setServiceInterface(UserService.class);
exporter.setRegistryPort(1192);
exporter.setReplaceExistingBinding(true);
return exporter;
}
Client configuration:
public #Bean RmiProxyFactoryBean getUserService() {
RmiProxyFactoryBean rmi = new RmiProxyFactoryBean();
rmi.setServiceInterface(UserService.class);
rmi.setServiceUrl("rmi://localhost:1192/UserService");
return rmi;
}
Test code :
User user = userService.getUser(String userName);
Works perfectly fine.
userService.save(user);
Save user throws RMI exception.
I made sure that the package name for User object in server and client is same. Still I am getting the exception.
Am I missing any configuration? How can I make RMI server to load the other classes?