Monday, December 23, 2019

Scala Mongo example with akka-http and akka-stream

Introduction

In this tutorial we shall create and CRUD web application in Scala. We will use MongoDB Scala Driver to communicate to the mongo database. It is officially supported Scala driver for MongoDB. Along with that we shall create a Rest API using akka-http module and akka-streams.

Prerequisites

  • Scala version: 2.13.1
  • Database: Mongo:3.4.23-xenial

Other dependencies - 


About the service/project

Application should be able to do CRUD operations on the in mongodb document. This application should also provide Rest apis to access and modify the data. So it is an employee management. We have employee details in a document called `employee`. We will create reset services to create, update and search the employee data.

Mongo Configuration

Codec Registry

Mongo documents required the codec information for marshal and un-marshal the data. This codecs are already written and available here. This repository have codec implementations for most of the available types. So first create the the java codec as below -

In the above code `Employee` is our mongo document class with the following details. 

Document Class

Employee document contains employee name and date of birth.

Database Details

`MongoClientSettings` is the companion object to configure the mongodb settings. 

In the above snippet; An Mongo client settings object is created that contains the configuration details for the connecting mongo database.

Collection Details

Collection details can be obtained from the database representation we get the previous step

This above step required for every collection to get the data.

JSON Support

We need formatter to format the date type to and from JSON format. We used Spray JSON here for this. Spray JSON providing automatic to and from JSON marshalling/un-marshalling using an in-scope *spray-json* protocol.

Repository

Repository contains the create, update, delete and search commands for the employee document. 

Actors to get the user data 

Employee actor received messages to perform different operation on the employee document. Actor shall call the actual service and then send the responds to the sender.

Routing Configuration



#1
GET /api/employee/create
To create employee data 
#2 
POST /api/employee/search
To search employee data
#3
PUT /api/employee/update
To update employee data
#4
DELETE /api/employee/delete
To delete user data

The routing code should look like this-


Web Server

This class is used to create http server and bind the endpoints with the http server. You can get more information in my previous blog.

Run Application

Start the mongodb docker container 

`docker-compose up -d`

Compile the code using below command

`sbt compile`
Run the application
`sbt run`
Now go to terminal, and run below https://httpie.org/ commands 

Create Employee Data

Search Employee Data

Update Employee Data

Check current data in mongodb

Update the data by id 

Search data after update 



Delete Employee data

Search employee data

Delete employee data using id

Search data after delete

Github links

Full code is available here to to explore and fork. Feel free to do whatever you want. ;)

Conclusion

We have seen here how to use akka http and streams to create rest services in scala. You can get more information here - 

Tuesday, December 10, 2019

Scala Rest API with akka-http

Introduction


In this tutorial we shall explore how we can use akka-http to create service with scala. Here we create CRUD service with akka actor and try to see how it work. 

Versions

Scala version: 2.13.1

SBT version: 1.3.4

Other dependencies - 

About the service/project

We’ll create two actors that communicate with each other to get the user data and user activity data. 

Data Classes

We need two data classes that keeps the user data and user activity data.

Repository

Repositories are used to fetch the data from the actual source of data. The actual source can be anything like another service or some database. We created `UserActivityRepository` that have only one method `queryHistoricalActivities` to fetch the user activity by `userId`.

Actors to get user data 

We need two actor classes for `UserDataActor` and `UserActivityActor`. `UserDataActor` received 4 types of methods `Get`, `Post`,`Put` and `Delete` to retrieve, create, update and delete the user data respectively.  Once a message received, User data will be sent to the sender asynchronously.


`UserActivityActor` retrieve the user active once it receives the message `Get` 

Routing Configuration

Now, we need to create routing details, to access the user details from rest endpoints. We needs following endpoints 


#1
GET /api/users/activity
Retrieve user and its activity details.
#2 
POST /api/user
To create user data
#3
PUT /api/user
To update user data
#4
DELETE /api/user
To delete user data


Routing code looks like below -


We have two `implicit` parameters in the routing config `implicit val userDataActorRef: ActorRef` and `implicit val system: ActorSystem`. `userDataActorRef` is used to get the user data. Since user details is required to register `UserActivityActor` we use actor system and implicit parameter to register `UserActivityActor` when we have user information available.


Web Server
This class is used to create http server and bind the endpoints with the http server. 


Run Application

Compile the code using below command

sbt compile

Run the application

sbt run

Now go to terminal, and run below httpie scripts 

Output of testing endpoints

Github links

Full code is available here to to explore and fork. Feel free to do whatever you want. ;)

Conclusion

We have seen here it’s easy to create rest services with akka and scala. You can get more information at
akka-http official document


Friday, November 30, 2018

Secure spring boot application with keycloak

In last blog post of this series we saw how we can configure keycloak for our application.
Now in this tutorial we
will see how we can use keycloak with spring boot.

Prerequisite
  • Docker
  • Keycloak

Version
  • Spring Boo: 1.5.17.RELEASE
  • Java: 1.8
  • Keycloak: 4.0.5-Final


Create sample spring boot application
Dependencies
  • Spring-boot-starter-web
  • Keycloak-spring-boot-starter

Create rest controller class


Secure App with keycloak
Add maven dependency for keycloak and spring security
  • spring-boot-starter-security
  • keycloak-spring-boot-starter

Configure keycloak server url and realms details in application.properties file


Configure keycloak security settings in the application
Add the blow class to configure the keycloak

KeycloakSecurityConfigurer.class extends KeycloakWebSecurityConfigurerAdapter.class
that
provide convenient base class for creating a WebSecurityConfigurer instance secured by Keycloak.

GrantedAuthoritiesMapper is mapping interface which use to convert case of the role used in the keycloak from
lower case to uppercase.

KeycloakAuthenticationProvider perform authentication process.

NullAuthenticatedSessionStrategy since we are using rest full service so we can provide null authenticated
session strategy.

KeycloakConfigResolver use to tell keycloak to use spring boot configuration.
Instead
use the configuration from the spring boot configuration resolver.

keycloakAuthenticationProcessingFilterRegistrationBean, keycloakPreAuthActionsFilterRegistrationBean are used
avoid re-registration of the filter.

Add security in rest controller SecuredResoureces
Running application

start the application using

mvn spring-boot:run


Call the admin api without security token.


Get access token for admin role


Access admin api with access token


Access user api with access token will give error because user role required for access user service.


Get access token for user role


Access user service



You can get the source code from Bitbucket

Setup keycloak sercurity for spring boot application

Setup Realm and clients in keycloak
This blog is the second part of the series of security spring boot application with keycloak. In first part we install setup in keycloak with docker you can see first part here.
Version:
Keycloak: 4.5.0.Final
Pre-requisites
Keycloak should be installed in the

Create realm
A realm secures and manages security metadata for a set of users, applications, and registered oauth clients. Users can be created within a specific realm within the Administration console.
Click on Add realm button

Input the realm name

Once realm created you will see this screen


Create Client
We need 2 clients one is for bearer-only client for the application, and another one is public client to get the access token

Create Public client
Once public client is created you will see the below screen


Create Bearer only client and set the access type to beare-only
Add new Admin role for the application client

Create Admin Client

 Create User Client
Create User for the application
Create two user with role admin with and user.

 Create admin user

 Set password

Assign admin role to user vik-admin


Similarly create another user account vik-user with user role


Get access and refresh token
User below curl to get the access token

Response


In the next blog we will se how to secure spring boot application. You can see the blog here.

Wednesday, November 28, 2018

Setup Keycloak with Docker


Introduction of Keycloak
Open Source Identity and Access Management For Modern Applications and Services. It add authentication to applications and secure services with minimum fuss. No need to deal with storing users or authenticating users. It's all available out of the box.

You'll even get advanced features such as User Federation, Identity Brokering and Social Login.
Prerequisites:
Docker:
Since we are using Docker to install Keycloak; it should be installed on your machine. If it is not you can download and install it from the link given below, it’s pretty straight forward.
Create docker compose file
  1. We use keycloak with mysql database to persist the user data.
  2. Use the below docker-compose.yml file to pull and start the docker server

docker-compose.yml


In docker compose file we povide default user name and password for the keycloak use and described in the docker hub for the keycloak image.
  • Our mysql and keycloak server are running on the docker network “Keycloak-network”.
Start keycloak and mysql server
  • Run “docker-compose up” command on the terminal, once the server up you can see the output as below -

  • Go the browser and type the url - http: //localhost:9001 Note: remember we expose the port in the docker-compose file ?

You can now login keycloak from the username and password you provided in docker-compose file. In our case we use username “admin” and password also ‘admin’



After login you will see the default realm ‘master’ as below -

Core concept and terms of keycloak -
Realms:
A realm manages a set of users, credentials, roles, and groups. A user belongs to and logs into a realm. Realms are isolated from one another and can only manage and authenticate the users that they control.

Groups:
Groups manage groups of users. Attributes can be defined for a group. You can map roles to a group as well. Users that become members of a group inherit the attributes and role mappings that group defines.

Clients:
Clients are entities that can request Keycloak to authenticate a user. Most often, clients are applications and services that want to use Keycloak to secure themselves and provide a single sign-on solution. Clients can also be entities that just want to request identity information or an access token so that they can securely invoke other services on the network that are secured by Keycloak.

Client scopes:
When a client is registered, you must define protocol mappers and role scope mappings for that client. It is often useful to store a client scope, to make creating new clients easier by sharing some common settings. This is also useful for requesting some claims or roles to be conditionally based on the value of scope parameter. Keycloak provides the concept of a client scope for this.

Client role:
Clients can define roles that are specific to them. This is basically a role namespace dedicated to the client.

Identity token:
A token that provides identity information about the user. Part of the OpenID Connect specification. You can get more details about this terms here !
Conclusion:
In this blog we learn how to setup keycloak using docker, in next blog we will create an application and secure it using keycloak.

Reference https:

Friday, February 23, 2018

Spring Security with JWT and Oauth2 with Spring Boot

Introduction-

In this article we shall see example of how to secure a spring boot rest application with Spring Boot2, Spring Security, Oauth2, and JWT token.


1. Source Code Repository -

The code used in this article is available in this repository GitHub.


2. Dependencies -


2.1. Versions -

  1. Spring Boot: 2.1.3.RELEASE
  2. Java: 1.8

3. Entity Class -


We create two Entity Classes, one is User and another is Role. User entity class contains user details like name, password, roles details, and role entity contains the role details. One User may have many roles hence we to create many-to-many relationship between User and Role Entity.


3.1. User Entity.java


Entity class that contains the user details.


3.2. Role.java


Entity class that contains the user role data.

4. Create CRUD Repository -


We create spring CRUD repository class, to access user credentials from the database.
Note: we create repository only for User entity class, because in User entity class we specify Many to Many relationship between User and Role entity, and @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) at line number 35 in User.java, will ensure that when new record save in User entity it will also save in Role entity.

4.1. UserRepository.java



5. Create a Spring boot Initialize class


This will boot the spring application.


Now we need to create initial data for users create data.sql file and put it into resource directory.




6. Controller class


Now create controller class to access the resources.


Now our basic application is created, just the start the application server to see the output.

use mvn spring-boot:run to run the application

After the server start just curl the below URL to check if everything is working correct or not

curl http://localhost:8080/app/listAll

Response -

[
  {
    "id": 1,
    "username": "vikas",
    "password": "$2a$04$lZj8KgBFkcPwgRWjH8DwBeCIR7HE6AsIZqTXu2VyeEw5sYLySNAGe",
    "firstName": "vikas",
    "lastName": "verma",
    "roles": [
      {
        "id": 1,
        "roleName": "ADMIN",
        "description": "admin role"
      }
    ]
  },
  {
    "id": 2,
    "username": "james",
    "password": "$2a$04$P2GbxPDh1MYNYyNn/bj.4.QxwDC2jze0xPQF4u6/cNpdkrPq3OdPy",
    "firstName": "james",
    "lastName": "james",
    "roles": [
      {
        "id": 1,
        "roleName": "ADMIN",
        "description": "admin role"
      },
      {
        "id": 2,
        "roleName": "USER",
        "description": "user role"
      }
    ]
  }

]

7. Authentication and Authorization


Now since our basic application is working, it’s time to add authentication and authorization to our application.
Add Dependencies for the Oauth2 Security


7.1. Set the properties related to security


The detail of the properties is as below -
1. security.encoding-strength=256 size of the encoding.
2. security.signing-key is the sign key used to encode the token.
3. security.security-realm realm of the authentication. see
4. security.jwt.client-id=client Client Id.
5. security.jwt.client-secret= It should be BCrypt format you can use this tool to encode any string to BCrypt
6. security.jwt.grant-type=password Grant type, it can be "password", "refresh-token".
7. security.jwt.scope-read=read read scope.
8. security.jwt.scope-write=write write scope.
9. security.jwt.resource-ids=testresource resource id.


7.3. JWTConfigProperties.java


Create a class to access the properties set in application property file.


7.4. UserDetailServiceImpl.java


To access the user credentials from database, we need to implement interface UserDetailsService. It is used throughout the framework as a user DAO. The interface requires only one read-only method, which simplifies support for new data-access strategies.


7.5. WebSecurityConfig.java


Configure the web security by extending the WebSecurityConfigurerAdapter class. It provides a convenient base class for creating a WebSecurityConfigurer instance. The implementation allows customization by overriding methods.

Step#1 Configure UserDetailsService to AuthenticationManager class, and add a password encoder.
*Autowire the userDetailsService instance.

Step#2 Now create AuthenticationManager bean

Since we are using password as grant-type we need to provide the AuthenticationManager implementation.

Step#3 Configure the JWT Token related beans -
tokenStore() Create a new JwtTokenStore with this token enhancer(accessTokenConverter).

accessTokenConverter() Configure JWT signing key. It can be either a simple MAC key or an RSA key. . RSA keys should be in OpenSSH format, as produced by ssh-keygen.

tokenServices() it is default implimentation of the tokenServices, it used to configure the resource related properties. In the tokenServices we used the default implementation of the TokeService interface, and set persistence strategy for token storage. the tokenStore, and configure to support the refresh token.

Now enable Web Security in the application, and Global Method security-

@EnableWebSecurity : It allow the Spring Security configuration defined in any WebSecurityConfigurer or more likely by extending the WebSecurityConfigurerAdapter base class and overriding individual methods.

@EnableGlobalMethodSecurity(prePostEnabled = true) : Enables Spring Security global method security.

@Order : Define the order the security filter chain. The priority of the WebSecurityConfigurerAdapter is more than the resourceServerConfigurationAdapter, hence we re-define the order WebSecurityConfigurerAdapter


8. Define Authentication Manager


Create a class AuthenticationServerConfig.java that extends  AuthorizationServerConfigurerAdapter.java to provides the default implementation for the AuthorizationServer. It is used to register the clients that can access the resource of the application, and also endpoints of the authorization server.


8.1. Configure Clients of the application


the code is self-explanatory, we jest configure the client details that are stored in memory. All the clients’ details are store in the application.property file.
*Autowire the jwtConfigProperties instance.


8.2. Configure the Authorization endpoints


*Autowire the jwtConfigProperties, jwtAccessTokenConverter, tokenStore and authenticationManager instance.
Configure the tokenstore, and tokenEnhancer with the AuthorizationServerEndpointsConfigurer
Configure the TokenStore, authenticationManager, and tokenEnhancerChain in the AuthorizationServerEndpointsConfigurer class.


8.3. Enable Authorization Server in the current application context



9. Resource Server Configuration


Create a class ResourceServerConfig.java that extends ResourceServerConfigurerAdapter.java
This class is used to configure the resourceIds, and the http request URLs that are allowed to access the application, and the URLs that need to be authenticated.


9.1. Configure Resource Id


*Autowire the jwtConfigProperties, defaultTokenService bean instances.
Resource id is configured in application.property file. defaultTokenService is created in class WebSecurityConfig.


9.2. Configure HttpSecurity


This configuration says, authenticate all request that contains "/app/**" in there URL.

9.3. Enable the resource server configuration


10. Modify the controller class


Finally set the roles that can access the application using @PostAuthorize annotation


11. Run The application


11.1 Run MySQL Database

Run below command to run the mysql db in docker

 docker-compose -f docker/docker-compose up


Now all the configurations are done, now we can run the application using below maven command in terminal

 mvn spring-boot:run


11.1 Access Resource with User credentials


After server started, We can get the access token. Run below command to get the access token-


11.1.1. Get Access Token



Result-

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzb3VyY2UiXSwidXNlcl9uYW1lIjoidmlrYXMiLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiZXhwIjoxNTUyMDA5ODM2LCJhdXRob3JpdGllcyI6WyJBRE1JTiJdLCJqdGkiOiI3YWJkOThhNC1hNjM4LTRmYmQtOWYzMC0zZWJiNDQ0M2FhMTciLCJjbGllbnRfaWQiOiJjbGllbnQifQ.P0UgLpAuswCs8iHsxT4q23TI1infsIMqZ1YtMlbfWe8",
  "token_type": "bearer",
  "expires_in": 43199,
  "scope": "read write",
  "jti": "7abd98a4-a638-4fbd-9f30-3ebb4443aa17"

}

11.2 Access Resource


11.2.1. Get the access token



** "Y2xpZW50OnNlY3JldA==" is Base64 encoded client-id:secret. you can encode and decode in base64 format using this site. The format of client-id and client-secret should be 'client-id:secret'.

Result-

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzb3VyY2UiXSwidXNlcl9uYW1lIjoidmlrYXMiLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiZXhwIjoxNTUyMDA5ODM2LCJhdXRob3JpdGllcyI6WyJBRE1JTiJdLCJqdGkiOiI3YWJkOThhNC1hNjM4LTRmYmQtOWYzMC0zZWJiNDQ0M2FhMTciLCJjbGllbnRfaWQiOiJjbGllbnQifQ.P0UgLpAuswCs8iHsxT4q23TI1infsIMqZ1YtMlbfWe8",
  "token_type": "bearer",
  "expires_in": 43199,
  "scope": "read write",
  "jti": "7abd98a4-a638-4fbd-9f30-3ebb4443aa17"

}


11.2.2. Access Admin Resources


To access the resource that required admin privilege you need to get the access token with user james/james, because this user have admin privilege



Result-

Access admin resources -
Hello Admin!!!
Access user resources -

Hello User!!!


11.2.3. Access the User resources


Result-
Hello User!!!

That's all for the Authentication and Authorization with Oauth2. You can access the resource from GitHub.