DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Enterprise RIA With Spring 3, Flex 4 and GraniteDS
  • Component Tests for Spring Cloud Microservices
  • Authentication With Remote LDAP Server in Spring WebFlux
  • Authentication With Remote LDAP Server in Spring Web MVC

Trending

  • Secrets Sprawl and AI: Why Your Non-Human Identities Need Attention Before You Deploy That LLM
  • Distributed Consensus: Paxos vs. Raft and Modern Implementations
  • Implementing Explainable AI in CRM Using Stream Processing
  • Securing the Future: Best Practices for Privacy and Data Governance in LLMOps
  1. DZone
  2. Coding
  3. Frameworks
  4. Spring Security With Radius Login

Spring Security With Radius Login

Want to learn more about using Spring Security on your app? Check out this post to learn more about implementing Spring Security with the Radius login.

By 
Pavel Sklenar user avatar
Pavel Sklenar
·
Oct. 12, 18 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
9.7K Views

Join the DZone community and get the full member experience.

Join For Free

In this example, we will secure a home page (/home) with Spring Security using Radius authentication.

Overview

Technology used:

  1. Spring Boot 2.0.4. RELEASE
  2. TinyRadius 1.0.1
  3. Embedded Tomcat 8.5.23

Table of Contents:

  1. Create a new base Spring Boot project with required dependencies
  2. Create a simple login using Spring Security
  3. Create your own RadiusAuthenticationProvider
  4. The simple test with a real Radius Server

1. Project Structure

Radius Login Eclipse Screen

2. Create a New Base Spring Boot Project

We will start with a new project generated by the Spring Initializr.Only two Spring dependencies are required: Security and Web.

Spring Initializr

The generated project is ready to run with embedded Tomcat, but we need to add other required dependencies. The first dependency is a tinyradius as a client library to be able to call the Radius server. The other two dependencies (jstl and tomcat-embed-jasper) are related to JSP pages, which will be used inside a login and a home page.

All required dependencies are shown here:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.hynnet</groupId>
            <artifactId>tinyradius</artifactId>
            <version>1.0.1</version>
</dependency>     


The Spring Initialzr usually did not generate any dummy pages, so we need to add our pages, login.jsp, and home.jsp.

We do not need an extra Controller class, so we register our pages into ViewControllerRegistry directly.

ViewController is required to be able to map view to its JSP page.

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("home");
        registry.addViewController("/home").setViewName("home");
        registry.addViewController("/login").setViewName("login");
    }

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/pages/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}


3. Create a Simple Login Using Spring Security

There are many examples on how to configure Spring Security, so check Google if you need to customize it. We do not need any special configuration, just to secure a home page. We will display a login page for non-authenticated users, it’s all, no more requirements, no roles.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }
}


4. Create Your Own RadiusAuthenticationProvider

You need to implement your own AuthenticationProvider, so the method authenticate is required:

@Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        RadiusPacket response = null;
        int attemptCount = 0;
        while (response == null && attemptCount++ < clients.size()) {
            response = authenticateInternally(clients.get(attemptCount - 1), username,
                    authentication.getCredentials().toString());
        }
        if (response == null) {
            logger.warn("User {}, calling radius does not return any value.", username);
            return null;
        }
        if (response.getPacketType() == RadiusPacket.ACCESS_ACCEPT) {
            logger.info("User {} successfully authenticated using radius", username);
            return new UsernamePasswordAuthenticationToken(username, "", new ArrayList<>());
        } else {
            logger.warn("User {}, returned response {}", username, response);
            return null;
        }
}


There is nothing special in this method except working with a response from the Radius server. We accept only RadiusPacket.ACCESS_ACCEPT, which indicates that our authentication has been successful.

The communication between our application (a.k.a. network access server – NAS) and a RADIUS server is implemented in the class NetworkAccessServer:

public RadiusPacket authenticate(String login, String password) throws IOException, RadiusException {
        AccessRequest ar = new AccessRequest(login, password);

        ar.setAuthProtocol(AccessRequest.AUTH_PAP);

        ar.addAttribute(NAS_PORT_ID, InetAddress.getLocalHost().getHostAddress());

        ar.addAttribute(NAS_IP_ADDRESS, "172.25.0.101");

        RadiusPacket response = radiusClient.authenticate(ar);
        return response;
}


I have used some commonly used parameters, e.g. NAS-IP-Address and NAS-Port-Id, but you can set any other settings depends on your server.

5. Simple Test With a Real Radius Server

We have prepared our application to make a real authentication test. Please check the project source code to download a fully working copy. Now, we can simply start the Spring Boot web app:

$mvn spring-boot:run


The home page (http://localhost:8080/) is password protected, so we need to log in first:

The real Radius server is required to make a real authentication test.

If you do not have any free Radius server to test, you can make your test against a Radius server running inside Docker. Thanks to Docker, you are able to run a real server in one minute. Check out this useful tutorial here.

When using the pre-configured Docker container, you can simply start a fully configured Radius server with this command:

$docker-compose up -d freeradius


My application contains a correct configuration to call this testing Radius server as well (the 2nd server’s configuration, servers are delimited by the semicolon):

com.pavelsklenar.radius.server=192.168.1.1,secret,500;127.0.0.1,SECRET,1000


The source code of this project could be found on my public GitHub profile. To prevent any other future changes, the fully compatible Radius server with configuration files is forked on my GitHub profile as well.

Note: To run this project in the IntelliJ Idea (in the version 2018.2.x and above) using their Spring Boot plugin, set in the Run configuration Working directory to $MODULE_WORKING_DIR$ . No other changes are required. Tips to remove provided an element in the pom.xml are not required anymore.

Some useful links about Spring Security:

  • Spring Security Authentication Provider
  • Spring Boot + Spring Security + Thymeleaf example
Spring Framework Spring Security

Published at DZone with permission of Pavel Sklenar, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Enterprise RIA With Spring 3, Flex 4 and GraniteDS
  • Component Tests for Spring Cloud Microservices
  • Authentication With Remote LDAP Server in Spring WebFlux
  • Authentication With Remote LDAP Server in Spring Web MVC

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!