Spring Security JWT Authentication example – RestAPIs SpringBoot + Spring MVC + Spring JPA + MySQL

spring-security-jwt-json-web-token-authentication-springboot-spring-jpa-mysql-crud-restapi-feature-image

JSON Web Token defines a compact and self-contained way for securely transmitting information as a JSON object.
In the tutorial, we show how to build a SpringBoot Security RestAPIs with JSON Web Token (JWT).

Related posts:
Spring Security – JDBC Authentication – SpringBoot + MySQL + Bootstrap
SQL Tutorial – MySQL Many-to-Many Relationship
Spring JPA Hibernate Many to Many – SpringBoot + PostgreSQL

Series:
Angular Spring Boot JWT Authentication example | Angular 6 + Spring Security + MySQL Full Stack

Technologies

– Spring Boot
– jjwt – 0.9.0
– Spring Security
– Spring JPA
– MySQL

JSON Web Token

JSON Web Token (JWT) defines a compact and self-contained way for securely transmitting information between parties as a JSON object.

Scenarios where JSON Web Tokens are useful:

  • Authorization: the most common scenario for using JWT. Single Sign On is a feature that widely uses JWT
  • Information Exchange: Because JWTs can be signed, JSON Web Tokens are a good way of securely transmitting information between parties.

JSON Web Tokens consist of 3 parts:

  • Header
  • Payload
  • Signature

-> JWT looks like Header-Base64-String.Payload-Base64-String.Signature-Base64-String

Header consists of two parts:

  • token type.
  • hashing algorithm.

-> Example:


{
  "alg": "HS256",
  "typ": "JWT"
}

Payload contains the claims. Claims are statements about an entity and additional information.
There are 3 types of claims ->

  • Registered claims -> These are a set of predefined claims: iss (issuer), exp (expiration time), sub (subject)
  • Public claims
  • Private claims

Example ->


{
  "sub": "thomasgkz",
  "iat": 1537603195,
  "exp": 1537689595
}

Signature -> To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

Example ->


HMACSHA512(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret
)

Combine all together, we get 3 Base64-URL strings separated by dots,

-> Example:


eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0aG9tYXNna3oiLCJpYXQiOjE1Mzc2MDMxOTUsImV4cCI6MTUzNzY4OTU5NX0.m2YMjTYmOnfR7nnVNxqCzWbQ2FhKRe1eiizxnC2TF4eAoEzKlwo7PheVkKcxj08ST3vB-ZOIhiORvYVfSgzcog

When accessing a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema.

-> Example:


Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0aG9tYXNna3oiLCJpYXQiOjE1Mzc2MDMxOTUsImV4cCI6MTUzNzY4OTU5NX0.m2YMjTYmOnfR7nnVNxqCzWbQ2FhKRe1eiizxnC2TF4eAoEzKlwo7PheVkKcxj08ST3vB-ZOIhiORvYVfSgzcog

Overview

Demo

Project Structure

We create a SpringBoot project as below:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-project-structure

model package defines 2 entities User & Role that have many-to-many relationship:

spring-security-jwt-springboot-restapi-jwt-json-web-token-authentication-many-to-many-user-role

repository package contains interfaces that use Hibernate JPA to store/retrieve data from MySQL database.
controller package defines RestAPIs for user signup/signin and testing protected resources that is secured with JWT.
message package defines payload data transferred from user agents (Browser/RestClient…) to RestAPIs and message back.
security package is the main part of the project that implements JWT security.

Goal

– We expose 2 RestAPIs to signup and signin:

  • /api/auth/signup -> sign up

    spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-up-form

  • /api/auth/signin -> sign in

    spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-in-with-user-role

– We expose 3 RestAPIs to test protected resources:


@GetMapping("/api/test/user")
@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
public String userAccess() {
	return ">>> User Contents!";
}

@GetMapping("/api/test/pm")
@PreAuthorize("hasRole('PM') or hasRole('ADMIN')")
public String projectManagementAccess() {
	return ">>> Board Management Project";
}

@GetMapping("/api/test/admin")
@PreAuthorize("hasRole('ADMIN')")
public String adminAccess() {
	return ">>> Admin Contents";
}
  • Access Successfully ->

    spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-user-api-success-with-user-role

  • Unauthorized ->

    spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-pm-api-fail-with-user-role

Practice

Create SpringBoot project

We create a SpringBoot project with below dependencies:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<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>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>
<dependency>
	<groupId>io.jsonwebtoken</groupId>
	<artifactId>jjwt</artifactId>
	<version>0.9.0</version>
</dependency>

Create Models

User.java model contains 5 attributes:

  • id
  • name
  • username
  • email
  • password

package com.ozenero.jwtauthentication.model;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

import org.hibernate.annotations.NaturalId;

@Entity
@Table(name = "users", uniqueConstraints = {
        @UniqueConstraint(columnNames = {
            "username"
        }),
        @UniqueConstraint(columnNames = {
            "email"
        })
})
public class User{
	@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    @Size(min=3, max = 50)
    private String name;

    @NotBlank
    @Size(min=3, max = 50)
    private String username;

    @NaturalId
    @NotBlank
    @Size(max = 50)
    @Email
    private String email;

    @NotBlank
    @Size(min=6, max = 100)
    private String password;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "user_roles", 
    	joinColumns = @JoinColumn(name = "user_id"), 
    	inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set roles = new HashSet<>();

    public User() {}

    public User(String name, String username, String email, String password) {
        this.name = name;
        this.username = username;
        this.email = email;
        this.password = password;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Set getRoles() {
        return roles;
    }

    public void setRoles(Set roles) {
        this.roles = roles;
    }
}

Role.java model contains 2 attributes:

  • id
  • rolename

package com.ozenero.jwtauthentication.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.NaturalId;

@Entity
@Table(name = "roles")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Enumerated(EnumType.STRING)
    @NaturalId
    @Column(length = 60)
    private RoleName name;

    public Role() {}

    public Role(RoleName name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public RoleName getName() {
        return name;
    }

    public void setName(RoleName name) {
        this.name = name;
    }
}

RoleName.java ->


package com.ozenero.jwtauthentication.model;

public enum  RoleName {
    ROLE_USER,
    ROLE_PM,
    ROLE_ADMIN
}

Implement Repository

UserRepository ->


package com.ozenero.jwtauthentication.repository;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.ozenero.jwtauthentication.model.User;

@Repository
public interface UserRepository extends JpaRepository {
    Optional findByUsername(String username);
    Boolean existsByUsername(String username);
    Boolean existsByEmail(String email);
}

RoleRepository.java ->


package com.ozenero.jwtauthentication.repository;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.ozenero.jwtauthentication.model.Role;
import com.ozenero.jwtauthentication.model.RoleName;

@Repository
public interface RoleRepository extends JpaRepository {
    Optional findByName(RoleName roleName);
}

Implement JWT Security

– Configure WebSecurityConfig.java:


package com.ozenero.jwtauthentication.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.ozenero.jwtauthentication.security.jwt.JwtAuthEntryPoint;
import com.ozenero.jwtauthentication.security.jwt.JwtAuthTokenFilter;
import com.ozenero.jwtauthentication.security.services.UserDetailsServiceImpl;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
		prePostEnabled = true
)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserDetailsServiceImpl userDetailsService;

    @Autowired
    private JwtAuthEntryPoint unauthorizedHandler;

    @Bean
    public JwtAuthTokenFilter authenticationJwtTokenFilter() {
        return new JwtAuthTokenFilter();
    }

    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable().
                authorizeRequests()
                .antMatchers("/api/auth/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        
        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

@EnableWebSecurity is used to enable web security in a project.
@EnableGlobalMethodSecurity(prePostEnabled = true) is used to enable Spring Security global method security.

-> Example:


@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
public String userAccess() {

@GetMapping("/api/test/pm")
@PreAuthorize("hasRole('PM') or hasRole('ADMIN')")

@GetMapping("/api/test/admin")
@PreAuthorize("hasRole('ADMIN')")

PasswordEncoder uses the BCrypt strong hashing function.

UserDetails Service

UserDetailsServiceImpl implements UserDetailsService that will override loadUserByUsername method.
loadUserByUsername method will find a record from users database tables to build a UserDetails object for authentication.


package com.ozenero.jwtauthentication.security.services;

import com.ozenero.jwtauthentication.model.User;
import com.ozenero.jwtauthentication.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    @Override
    @Transactional
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
    	
        User user = userRepository.findByUsername(username)
                	.orElseThrow(() -> 
                        new UsernameNotFoundException("User Not Found with -> username or email : " + username)
        );

        return UserPrinciple.build(user);
    }
}

-> UserPrinciple will implement UserDetails.
UserPrinciple is not used directly by Spring Security for security purposes.
It simply stores user information which is later encapsulated into Authentication objects. This allows non-security related user information (such as email addresses, telephone numbers etc) to be stored.


package com.ozenero.jwtauthentication.security.services;

import com.ozenero.jwtauthentication.model.User;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class UserPrinciple implements UserDetails {
	private static final long serialVersionUID = 1L;

	private Long id;

    private String name;

    private String username;

    private String email;

    @JsonIgnore
    private String password;

    private Collection authorities;

    public UserPrinciple(Long id, String name, 
			    		String username, String email, String password, 
			    		Collection authorities) {
        this.id = id;
        this.name = name;
        this.username = username;
        this.email = email;
        this.password = password;
        this.authorities = authorities;
    }

    public static UserPrinciple build(User user) {
        List authorities = user.getRoles().stream().map(role ->
                new SimpleGrantedAuthority(role.getName().name())
        ).collect(Collectors.toList());

        return new UserPrinciple(
                user.getId(),
                user.getName(),
                user.getUsername(),
                user.getEmail(),
                user.getPassword(),
                authorities
        );
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public Collection getAuthorities() {
        return authorities;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        
        UserPrinciple user = (UserPrinciple) o;
        return Objects.equals(id, user.id);
    }
}

JWT Authentication Classes

JwtAuthTokenFilter extends OncePerRequestFilter.

org.springframework.web.filter.OncePerRequestFilter
-> Executes once per request. This is a filter base class that is used to guarantee a single execution per request dispatch. It provides a doFilterInternal method with HttpServletRequest and HttpServletResponse arguments.

In JwtAuthTokenFilter class, the doFilterInternal method will do:

  • get JWT token from header
  • validate JWT
  • parse username from validated JWT
  • load data from users table, then build an authentication object
  • set the authentication object to Security Context

package com.ozenero.jwtauthentication.security.jwt;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import com.ozenero.jwtauthentication.security.services.UserDetailsServiceImpl;

public class JwtAuthTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtProvider tokenProvider;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthTokenFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request, 
    								HttpServletResponse response, 
    								FilterChain filterChain) 
    										throws ServletException, IOException {
        try {
        	
            String jwt = getJwt(request);
            if (jwt!=null && tokenProvider.validateJwtToken(jwt)) {
                String username = tokenProvider.getUserNameFromJwtToken(jwt);

                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                UsernamePasswordAuthenticationToken authentication 
                		= new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception e) {
            logger.error("Can NOT set user authentication -> Message: {}", e);
        }

        filterChain.doFilter(request, response);
    }

    private String getJwt(HttpServletRequest request) {
        String authHeader = request.getHeader("Authorization");
        	
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
        	return authHeader.replace("Bearer ","");
        }

        return null;
    }
}

JwtAuthEntryPoint is used to handle Error exception when having unauthorized requests.


package com.ozenero.jwtauthentication.security.jwt;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

@Component
public class JwtAuthEntryPoint implements AuthenticationEntryPoint {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthEntryPoint.class);
    
    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException e) 
                        		 throws IOException, ServletException {
    	
        logger.error("Unauthorized error. Message - {}", e.getMessage());
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error -> Unauthorized");
    }
}

JwtProvider is an util class -> it implements useful functions:

  • generate a JWT token
  • valiate a JWT token
  • parse username from JWT token

package com.ozenero.jwtauthentication.security.jwt;

import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import com.ozenero.jwtauthentication.security.services.UserPrinciple;

import java.util.Date;

@Component
public class JwtProvider {

    private static final Logger logger = LoggerFactory.getLogger(JwtProvider.class);

    @Value("${ozenero.app.jwtSecret}")
    private String jwtSecret;

    @Value("${ozenero.app.jwtExpiration}")
    private int jwtExpiration;

    public String generateJwtToken(Authentication authentication) {

        UserPrinciple userPrincipal = (UserPrinciple) authentication.getPrincipal();

        return Jwts.builder()
		                .setSubject((userPrincipal.getUsername()))
		                .setIssuedAt(new Date())
		                .setExpiration(new Date((new Date()).getTime() + jwtExpiration))
		                .signWith(SignatureAlgorithm.HS512, jwtSecret)
		                .compact();
    }

    public String getUserNameFromJwtToken(String token) {
        return Jwts.parser()
			                .setSigningKey(jwtSecret)
			                .parseClaimsJws(token)
			                .getBody().getSubject();
    }

    public boolean validateJwtToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
            return true;
        } catch (SignatureException e) {
            logger.error("Invalid JWT signature -> Message: {} ", e);
        } catch (MalformedJwtException e) {
            logger.error("Invalid JWT token -> Message: {}", e);
        } catch (ExpiredJwtException e) {
            logger.error("Expired JWT token -> Message: {}", e);
        } catch (UnsupportedJwtException e) {
            logger.error("Unsupported JWT token -> Message: {}", e);
        } catch (IllegalArgumentException e) {
            logger.error("JWT claims string is empty -> Message: {}", e);
        }
        
        return false;
    }
}

Implement RestControllers

Create Payload Message

LoginForm.java contains username & password ->


package com.ozenero.jwtauthentication.message.request;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

public class LoginForm {
    @NotBlank
    @Size(min=3, max = 60)
    private String username;

    @NotBlank
    @Size(min = 6, max = 40)
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

SignUpForm.java contains:

  • name
  • username
  • email
  • role
  • password

package com.ozenero.jwtauthentication.message.request;

import java.util.Set;

import javax.validation.constraints.*;

public class SignUpForm {
    @NotBlank
    @Size(min = 3, max = 50)
    private String name;

    @NotBlank
    @Size(min = 3, max = 50)
    private String username;

    @NotBlank
    @Size(max = 60)
    @Email
    private String email;
    
    private Set role;
    
    @NotBlank
    @Size(min = 6, max = 40)
    private String password;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    
    public Set getRole() {
    	return this.role;
    }
    
    public void setRole(Set role) {
    	this.role = role;
    }
}

JwtResponse.java is returned by SpringBoot server after successful authentication, it contains 2 parts:

  • JWT Token
  • Schema Type of Token

package com.ozenero.jwtauthentication.message.response;

public class JwtResponse {
    private String token;
    private String type = "Bearer";

    public JwtResponse(String accessToken) {
        this.token = accessToken;
    }

    public String getAccessToken() {
        return token;
    }

    public void setAccessToken(String accessToken) {
        this.token = accessToken;
    }

    public String getTokenType() {
        return type;
    }

    public void setTokenType(String tokenType) {
        this.type = tokenType;
    }
}

RestAPIs Controller

AuthRestAPIs.java defines 2 APIs:

  • /api/auth/signup: sign up
    -> check username/email is already in use.
    -> create User object
    -> store to database
  • /api/auth/signin: sign in
    -> attempt to authenticate with AuthenticationManager bean.
    -> add authentication object to SecurityContextHolder
    -> Generate JWT token, then return JWT to client

package com.ozenero.jwtauthentication.controller;

import java.util.HashSet;
import java.util.Set;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ozenero.jwtauthentication.message.request.LoginForm;
import com.ozenero.jwtauthentication.message.request.SignUpForm;
import com.ozenero.jwtauthentication.message.response.JwtResponse;
import com.ozenero.jwtauthentication.model.Role;
import com.ozenero.jwtauthentication.model.RoleName;
import com.ozenero.jwtauthentication.model.User;
import com.ozenero.jwtauthentication.repository.RoleRepository;
import com.ozenero.jwtauthentication.repository.UserRepository;
import com.ozenero.jwtauthentication.security.jwt.JwtProvider;

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/api/auth")
public class AuthRestAPIs {

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    UserRepository userRepository;

    @Autowired
    RoleRepository roleRepository;

    @Autowired
    PasswordEncoder encoder;

    @Autowired
    JwtProvider jwtProvider;

    @PostMapping("/signin")
    public ResponseEntity authenticateUser(@Valid @RequestBody LoginForm loginRequest) {

        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        loginRequest.getUsername(),
                        loginRequest.getPassword()
                )
        );

        SecurityContextHolder.getContext().setAuthentication(authentication);

        String jwt = jwtProvider.generateJwtToken(authentication);
        return ResponseEntity.ok(new JwtResponse(jwt));
    }

    @PostMapping("/signup")
    public ResponseEntity registerUser(@Valid @RequestBody SignUpForm signUpRequest) {
        if(userRepository.existsByUsername(signUpRequest.getUsername())) {
            return new ResponseEntity("Fail -> Username is already taken!",
                    HttpStatus.BAD_REQUEST);
        }

        if(userRepository.existsByEmail(signUpRequest.getEmail())) {
            return new ResponseEntity("Fail -> Email is already in use!",
                    HttpStatus.BAD_REQUEST);
        }

        // Creating user's account
        User user = new User(signUpRequest.getName(), signUpRequest.getUsername(),
                signUpRequest.getEmail(), encoder.encode(signUpRequest.getPassword()));

        Set strRoles = signUpRequest.getRole();
        Set roles = new HashSet<>();

        strRoles.forEach(role -> {
        	switch(role) {
	    		case "admin":
	    			Role adminRole = roleRepository.findByName(RoleName.ROLE_ADMIN)
	                .orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
	    			roles.add(adminRole);
	    			
	    			break;
	    		case "pm":
	            	Role pmRole = roleRepository.findByName(RoleName.ROLE_PM)
	                .orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
	            	roles.add(pmRole);
	            	
	    			break;
	    		default:
	        		Role userRole = roleRepository.findByName(RoleName.ROLE_USER)
	                .orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
	        		roles.add(userRole);        			
        	}
        });
        
        user.setRoles(roles);
        userRepository.save(user);

        return ResponseEntity.ok().body("User registered successfully!");
    }
}

TestRestAPIs define 3 RestAPIs:

  • /api/test/user -> access by users has USER_ROLE or ADMIN_ROLE
  • /api/test/pm -> access by users has USER_PM or ADMIN_ROLE
  • /api/test/admin -> access by users has ADMIN_ROLE

package com.ozenero.jwtauthentication.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestRestAPIs {
	
	@GetMapping("/api/test/user")
	@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
	public String userAccess() {
		return ">>> User Contents!";
	}
	
	@GetMapping("/api/test/pm")
	@PreAuthorize("hasRole('PM') or hasRole('ADMIN')")
	public String projectManagementAccess() {
		return ">>> Board Management Project";
	}
	
	@GetMapping("/api/test/admin")
	@PreAuthorize("hasRole('ADMIN')")
	public String adminAccess() {
		return ">>> Admin Contents";
	}
}

Application Properties

application.properties file ->


spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=12345
spring.jpa.generate-ddl=true

# App Properties
ozenero.app.jwtSecret=jwtGrokonezSecretKey
ozenero.app.jwtExpiration=86400

Run & Check Results

Start SpringBoot

– Start Springboot server by commandline mvn spring-boot:run

– Check database tables ->

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-authentication-mysql-tables-schema

– Insert data to roles table ->


INSERT INTO roles(name) VALUES('ROLE_USER');
INSERT INTO roles(name) VALUES('ROLE_PM');
INSERT INTO roles(name) VALUES('ROLE_ADMIN');

SignUp

Sign-Up 3 users:

  • Jack has ROLE_USER role
  • Adam has ROLE_PM & ROLE_USER roles
  • Thomas has ROLE_ADMIN role

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-up-form

– Check database’s tables ->

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-data-in-tables-after-sign-up

SignIn and Access Protected Resources

Jack can access api/test/user url, can NOT access others.

-> Sign In:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-in-with-user-role

-> Access Protected Resources:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-user-api-success-with-user-role

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-pm-api-fail-with-user-role

Adam can access api/test/user and api/test/pm url.
Can NOT access /api/test/admin url.

-> Sign In:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-in-with-admin-role-thomas

-> Access Protected Resources:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-user-api-success-with-pm-role-adam

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-pm-api-success-with-pm-role-adam

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-admin-api-fail-with-pm-role-adam

Thomas can access all URLs.

-> Sign In:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-sign-in-with-pm-role-adam

-> Access Protected Resource:

spring-security-jwt-authentication-restapi-springboot-spring-mvc-spring-jpa-mysql-access-admin-api-success-with-admin-role-admin

SourceCode

SpringBootJwtAuthentication

4,896 thoughts on “Spring Security JWT Authentication example – RestAPIs SpringBoot + Spring MVC + Spring JPA + MySQL”

    1. I say the same. This is the best tutorial I ever read. I’m from Brazil, and I couldn’t find a tutorial like this one in portuguese or in english. I don’t speak english very well, but I could understand all this tutorial. Thanks a lot! 😀

  1. Hi ozenero
    thank you for your sharing. I have a question, shall we remove the UsernamePasswordFilter from the inctercepters of http.

  2. Hello,

    I got this message when I tried to signin: Unable to load class named [io.jsonwebtoken.impl.DefaultJwtBuilder]

    my io.jsonwebtoken version is 0.10.5

  3. Hello, Mr. Grokonez.
    Firstly I would like to thank for the tuto, it’s very comprehensive.
    But I have an issue. I m using Eclipse JEE Photon, when I m trying to run your project it giving this error -> Error: Could not find or load main class SpringBootJwtAuthenticationApplication

    1. Hi Tomas, Is everything worked with you? because When running the project the tables are not got created. So I dont know what to do, any suggestion plz?

      1. Hi Ayind I’m using HSQLDB. I just had to update it’s version so that JpaRepository can work with it. If that’s not the case then maybe you’re misconfigured something in application.properties file.

  4. Hello, Excuse my English, I tried to implement this in payara server and I could not. Is there any way to do it ?. Thank you.

  5. Hello, great tutorial, I have tried to do in a war to deploy it in payara, when I do the test it generates the token well, but after accessing a resource it says not authorized, to a sending the token. could you give me a suggestion? Thank you. Excuse me, I’m learning English.

  6. Hello! I need help, I have worked on this project last week and it was working fine. but today when trying to log in with the registered users it gives back the token and use them for testing it says token expired. plz, any help? thanks in advance

  7. Is it normal to have access to the password after signing up , I’ve got it using logger.info(loginRequest.getPassword()) in the authenticateUser method .

  8. Hi Grokonez,
    The tutorial is really good. The JWT token had to be added to HTTP Headers so that, for each and every request the JWT will check for the particular user. As we are not using session in REST, JWT to be added to the HTTP Headers.
    Where this logic has been implemented in the code.?

    Thanks
    Srinivas. P.

    1. Hi Srinivas Pakala,

      You can check the logic in authenticateUser with @PostMapping("/signin").

      Regards,

  9. It return 403 Forbidden response when trying to get all the endpoints. Why is it giving this message could you help me please and thankyou.

  10. I can’t thank you enough. You’re the man!!!
    For those who want the angular part, it is quite easy. A quick search on google and you’ll find it.

  11. when I compile here is the error that appears help me please :

    . ____ _ __ _ _
    /\\ / ___’_ __ _ _(_)_ __ __ _ \ \ \ \
    ( ( )\___ | ‘_ | ‘_| | ‘_ \/ _` | \ \ \ \
    \\/ ___)| |_)| | | | | || (_| | ) ) ) )
    ‘ |____| .__|_| |_|_| |_\__, | / / / /
    =========|_|==============|___/=/_/_/_/
    :: Spring Boot :: (v2.0.5.RELEASE)

    2019-05-26 12:25:03.294 INFO 5256 — [ main] j.SpringBootJwtAuthenticationApplication : Starting SpringBootJwtAuthenticationApplication on Androids with PID 5256 (C:\Users\moh\eclipse-workspace\SpringBootJwtAuthentication\target\classes started by moh in C:\Users\moh\eclipse-workspace\SpringBootJwtAuthentication)
    2019-05-26 12:25:03.305 INFO 5256 — [ main] j.SpringBootJwtAuthenticationApplication : No active profile set, falling back to default profiles: default
    2019-05-26 12:25:03.447 INFO 5256 — [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2aece37d: startup date [Sun May 26 12:25:03 UTC 2019]; root of context hierarchy
    2019-05-26 12:25:07.378 INFO 5256 — [ main] trationDelegate$BeanPostProcessorChecker : Bean ‘org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration’ of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$bfcf34b8] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2019-05-26 12:25:07.553 INFO 5256 — [ main] trationDelegate$BeanPostProcessorChecker : Bean ‘org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration’ of type [org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration$$EnhancerBySpringCGLIB$$587cfcf2] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2019-05-26 12:25:07.576 INFO 5256 — [ main] trationDelegate$BeanPostProcessorChecker : Bean ‘objectPostProcessor’ of type [org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2019-05-26 12:25:07.583 INFO 5256 — [ main] trationDelegate$BeanPostProcessorChecker : Bean ‘org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler@443dbe42’ of type [org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2019-05-26 12:25:07.598 INFO 5256 — [ main] trationDelegate$BeanPostProcessorChecker : Bean ‘org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration’ of type [org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerBySpringCGLIB$$7d519fa4] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2019-05-26 12:25:07.633 INFO 5256 — [ main] trationDelegate$BeanPostProcessorChecker : Bean ‘methodSecurityMetadataSource’ of type [org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2019-05-26 12:25:08.850 INFO 5256 — [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
    2019-05-26 12:25:08.945 INFO 5256 — [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
    2019-05-26 12:25:08.946 INFO 5256 — [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.34
    2019-05-26 12:25:08.969 INFO 5256 — [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_201\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Program Files/Java/jre1.8.0_211/bin/server;C:/Program Files/Java/jre1.8.0_211/bin;C:/Program Files/Java/jre1.8.0_211/lib/amd64;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\Microsoft MPI\Bin\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\;C:\Program Files\Microsoft SQL Server\140\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\140\DTS\Binn\;C:\Program Files\Microsoft SQL Server\140\DTS\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\Java\jdk-9.0.1;C:\OpenSSL\bin;C:\Program Files\Java\jdk1.8.0_201;C:\Program Files\nodejs\;C:\Program Files\Java\jre-10;C:\Program Files\Java\jre-9.0.1;C:\Program Files\Java\jre1.8.0_211;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files\dotnet\;C:\Users\moh\AppData\Roaming\npm;C:\Users\moh\AppData\Local\Programs\Microsoft VS Code\bin;C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.1\bin;;C:\Users\moh\Desktop\eclipse-jee-2018-09-win32-x86_64;;.]
    2019-05-26 12:25:09.400 INFO 5256 — [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
    2019-05-26 12:25:09.401 INFO 5256 — [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 5969 ms
    2019-05-26 12:25:10.713 INFO 5256 — [ost-startStop-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 – Starting…
    2019-05-26 12:25:13.687 INFO 5256 — [ost-startStop-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 – Start completed.
    2019-05-26 12:25:14.082 INFO 5256 — [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit ‘default’
    2019-05-26 12:25:14.171 INFO 5256 — [ost-startStop-1] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
    name: default
    …]
    2019-05-26 12:25:14.970 INFO 5256 — [ost-startStop-1] org.hibernate.Version : HHH000412: Hibernate Core {5.2.17.Final}
    2019-05-26 12:25:15.016 INFO 5256 — [ost-startStop-1] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
    2019-05-26 12:25:15.471 INFO 5256 — [ost-startStop-1] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
    2019-05-26 12:25:16.061 INFO 5256 — [ost-startStop-1] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
    Hibernate: alter table user_roles add constraint FKh8ciramu9cc9q3qcqiv4ue8a6 foreign key (role_id) references roles (id)
    Hibernate: alter table user_roles add constraint FKhfh9dx7w3ubf1co1vdev94g3f foreign key (user_id) references users (id)
    2019-05-26 12:25:20.864 INFO 5256 — [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit ‘default’
    2019-05-26 12:25:22.858 ERROR 5256 — [ost-startStop-1] o.s.b.web.embedded.tomcat.TomcatStarter : Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name ‘authenticationJwtTokenFilter’: Unsatisfied dependency expressed through field ‘tokenProvider’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘jwtProvider’: Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder ‘ozenero.app.jwtSecret’ in value “${ozenero.app.jwtSecret}”
    2019-05-26 12:25:23.118 INFO 5256 — [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
    2019-05-26 12:25:23.151 WARN 5256 — [ost-startStop-1] o.a.c.loader.WebappClassLoaderBase : The web application [ROOT] appears to have started a thread named [HikariPool-1 housekeeper] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
    sun.misc.Unsafe.park(Native Method)
    java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
    java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    java.lang.Thread.run(Thread.java:748)
    2019-05-26 12:25:23.196 WARN 5256 — [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization – cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
    2019-05-26 12:25:23.200 INFO 5256 — [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit ‘default’
    2019-05-26 12:25:23.209 INFO 5256 — [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 – Shutdown initiated…
    2019-05-26 12:25:23.263 INFO 5256 — [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 – Shutdown completed.
    2019-05-26 12:25:23.303 INFO 5256 — [ main] ConditionEvaluationReportLoggingListener :

    Error starting ApplicationContext. To display the conditions report re-run your application with ‘debug’ enabled.
    2019-05-26 12:25:23.405 ERROR 5256 — [ main] o.s.boot.SpringApplication : Application run failed

    org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at com.ozenero.jwtauthentication.SpringBootJwtAuthenticationApplication.main(SpringBootJwtAuthenticationApplication.java:10) [classes/:na]
    Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:126) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.(TomcatWebServer.java:86) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:413) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:174) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    … 8 common frames omitted
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘authenticationJwtTokenFilter’: Unsatisfied dependency expressed through field ‘tokenProvider’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘jwtProvider’: Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder ‘ozenero.app.jwtSecret’ in value “${ozenero.app.jwtSecret}”
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1341) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:226) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:182) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:177) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:159) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.(ServletContextInitializerBeans.java:81) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:250) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:237) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:54) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5245) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1420) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1410) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_201]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_201]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_201]
    at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_201]
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘jwtProvider’: Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder ‘ozenero.app.jwtSecret’ in value “${ozenero.app.jwtSecret}”
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:378) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1341) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1135) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    … 25 common frames omitted
    Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder ‘ozenero.app.jwtSecret’ in value “${ozenero.app.jwtSecret}”
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:172) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:124) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:237) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:211) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:175) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:839) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1083) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    … 36 common frames omitted

  12. After adding the filter I am getting 403 error for signup URL. But signu/signin URLs are permitted by configuration. Any help.

    @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.cors().and().csrf().disable().
                    authorizeRequests()
                    .antMatchers("/api/public/**").permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
            
            http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        }
    
  13. Hi ozenero, if there is a microservices system and this project is a authentication service, how other services could use (understand) this service is for authentication? Could you give an example or guide or article link? Thank so much!

  14. I just want to say that this blog is the best in programming tutorials, the code is always available, explained step by step and very detailed. Certainly the site is written by extremely enthusiastic people. Thanks very much!!!

  15. Error creating bean with name ‘springSecurityFilterChain’ defined in class path resource [
    d by: java.lang.IllegalArgumentException: A UserDetailsService must be set
    ihave this prob

  16. I get error when i run username and password is empty,
    why this throw error : UsernameNotFoundException(“User Not Found with -> username or email : ” + Username));

    {
    “timestamp”: “2020-04-23T07:47:04.505+0000”,
    “status”: 401,
    “error”: “Unauthorized”,
    “message”: “Error -> Unauthorized”,
    “path”: “/api/auth/Signin”
    }

  17. i am not able to run this project after complete all the configuration i am geting the error below
    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/C:/Users/SSS-SSISM/.m2/repository/org/springframework/spring-core/5.0.9.RELEASE/spring-core-5.0.9.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
    WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
    WARNING: Use –illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release

  18. hello, thanks for your post, it is very good to understand spring safety,
    if you could clarify the next question question. I would really appreciate it.

    why do you use
    USER, ADMIN and PM
    instead of
    ROLE_USER, ROLE_ADMIN, and ROLE_PM,
    in @PreAuthorize?

    @PreAuthorize(“hasRole(‘USER’) or hasRole(‘ADMIN’)”)
    @PreAuthorize(“hasRole(‘PM’) or hasRole(‘ADMIN’)”)

  19. 890323 667074Id should consult you here. Which is not some thing Its my job to do! I spend time reading an article that may possibly get individuals to believe. Also, several thanks for permitting me to comment! 121512

  20. 459797 199242Great day! This post could not be written any far better! Reading this post reminds me of my previous room mate! He always kept chatting about this. I will forward this write-up to him. Fairly certain he will have a very good read. Thanks for sharing! 200496

  21. Normally I do not learn article on blogs, however I wish to say that this write-up very pressured me to take a look at and do so! Your writing taste has been amazed me. Thanks, very great article.

  22. This key fact page seems to be get so much website. Can you advertise it? This provides for a important distinct disregard in concerns. Perhaps utilizing a specific product sincere or possibly a lot of to deliver home elevators is the main component.

  23. Excellent post. I used to be checking continuously this blog and I’m impressed! Extremely useful information specifically the closing phase 🙂 I maintain such info a lot. I used to be seeking this certain information for a long time. Thank you and good luck.

  24. Thanks for each of your efforts on this web site. Kim really loves managing investigation and it’s easy to understand why. All of us know all about the lively ways you present invaluable items via the web site and therefore invigorate response from other individuals on this article plus our favorite daughter is truly being taught a whole lot. Have fun with the rest of the new year. You are always conducting a superb job.

  25. You can definitely see your expertise within the work you write. The world hopes for more passionate writers like you who are not afraid to say how they believe. All the time follow your heart. “Experience is a good school, but the fees are high.” by Heinrich Heine.

  26. In this grand scheme of things you secure a B+ with regard to effort. Where you actually misplaced me was on the particulars. You know, people say, the devil is in the details… And that could not be more correct right here. Having said that, let me say to you just what exactly did give good results. Your article (parts of it) is definitely extremely convincing which is most likely the reason why I am taking an effort in order to comment. I do not really make it a regular habit of doing that. Secondly, although I can notice the leaps in logic you come up with, I am definitely not confident of exactly how you appear to unite your details which inturn produce the conclusion. For now I will, no doubt subscribe to your issue but wish in the near future you connect your dots much better.

  27. I’m truly enjoying the design and layout of your website. It’s a very easy on the eyes which makes it much more enjoyable for me to come here and visit more often. Did you hire out a designer to create your theme? Great work!

  28. Howdy just wanted to give you a brief heads up and let you know a
    few of the images aren’t loading properly. I’m not sure why but I
    think its a linking issue. I’ve tried it in two different browsers
    and both show the same results.

  29. Hi there! I know this is kind of off-topic however I had to ask.
    Does operating a well-established website such as yours require a large amount of work?

    I’m completely new to operating a blog but I do write in my
    journal everyday. I’d like to start a blog so I can share my personal experience and feelings online.
    Please let me know if you have any kind of recommendations or
    tips for brand new aspiring blog owners. Appreciate it!

  30. Hi I am so thrilled I found your blog, I really found you by error, while I was browsing on Google
    for something else, Nonetheless I am here now and
    would just like to say many thanks for a remarkable post and a all
    round thrilling blog (I also love the theme/design), I don’t have time to browse it all at the moment but I have bookmarked it
    and also added in your RSS feeds, so when I have time I will be back
    to read much more, Please do keep up the fantastic jo.

  31. Howdy! I know this is kinda off topic however I’d figured I’d ask.
    Would you be interested in exchanging links or maybe guest authoring a blog article or vice-versa?
    My website discusses a lot of the same subjects as yours and
    I believe we could greatly benefit from each other. If you happen to
    be interested feel free to shoot me an e-mail. I look forward to hearing from you!
    Fantastic blog by the way!

  32. May I just say what a relief to uncover a person that actually understands what they are discussing
    on the net. You certainly realize how to bring an issue to light
    and make it important. A lot more people need
    to check this out and understand this side of your story.
    I can’t believe you aren’t more popular since you definitely have the gift.

  33. It is the best time to make a few plans for the longer term and
    it’s time to be happy. I’ve read this publish and
    if I may I want to suggest you some interesting issues or tips.
    Maybe you could write subsequent articles referring to this article.
    I want to read even more things about it!

  34. Hey there! I’ve been reading your web site for a while now and finally got the courage to go ahead
    and give you a shout out from Houston Texas!

    Just wanted to tell you keep up the excellent job!

  35. You actually make it seem really easy with your presentation but
    I to find this topic to be actually something which I think I’d by no means understand.
    It seems too complex and very large for me. I’m having a look forward in your next put up, I will try to get the
    cling of it!

  36. Hello there! I know this is kind of off topic but I was wondering which blog
    platform are you using for this site? I’m getting sick and tired of WordPress because I’ve had issues with hackers and I’m looking at alternatives for another platform.
    I would be awesome if you could point me in the direction of a good platform.

  37. I was wondering if you ever thought of changing the structure of your
    site? Its very well written; I love what youve got to say.
    But maybe you could a little more in the way of content so people
    could connect with it better. Youve got an awful lot of text
    for only having 1 or two images. Maybe you could space it out better?

  38. I don’t know whether it’s just me or if everyone else
    experiencing issues with your website. It appears like some of
    the text in your content are running off
    the screen. Can somebody else please comment and let me know if this is happening
    to them as well? This might be a problem with my browser because I’ve had this happen previously.
    Thank you

  39. Hello just wanted to give you a quick heads up and
    let you know a few of the images aren’t loading properly. I’m not sure
    why but I think its a linking issue. I’ve tried it
    in two different web browsers and both show the same results.

  40. It’s a shame you don’t have a donate button! I’d definitely donate to this fantastic blog!
    I guess for now i’ll settle for bookmarking and adding your RSS feed to my Google account.

    I look forward to brand new updates and will share this site with my Facebook group.
    Talk soon!

  41. Howdy! This is kind of off topic but I need some advice from an established
    blog. Is it hard to set up your own blog? I’m not very
    techincal but I can figure things out pretty quick. I’m
    thinking about creating my own but I’m not sure where to start.
    Do you have any points or suggestions? Cheers

  42. Howdy! This is kind of off topic but I need some advice from an established blog.
    Is it tough to set up your own blog? I’m not very techincal but I can figure things out pretty quick.
    I’m thinking about creating my own but I’m not sure where to start.

    Do you have any tips or suggestions? Appreciate it

  43. This is very interesting, You’re a very skilled blogger.
    I have joined your feed and look forward to seeking more of your excellent post.
    Also, I have shared your web site in my social networks!

  44. Sweet blog! I found it while surfing around on Yahoo
    News. Do you have any tips on how to get listed in Yahoo News?
    I’ve been trying for a while but I never seem to get there!
    Cheers

  45. It is appropriate time to make some plans for the long run and it’s time to
    be happy. I have read this submit and if I could I wish to recommend you few attention-grabbing things or tips.
    Perhaps you could write next articles relating to this article.
    I wish to learn even more things about it!

  46. Fascinating blog! Is your theme custom made or did you download it
    from somewhere? A design like yours with a few simple adjustements
    would really make my blog shine. Please let me know where you got your design. Thanks
    a lot

  47. Hi there, I discovered your website by means of
    Google even as looking for a related topic, your site
    got here up, it seems to be good. I’ve bookmarked it in my google bookmarks.

    Hi there, just was aware of your blog thru Google, and found that
    it’s really informative. I’m gonna watch out for brussels.
    I’ll appreciate for those who continue this in future.

    A lot of people can be benefited out of your writing.
    Cheers!

  48. This is really fascinating, You’re an excessively professional blogger.

    I have joined your rss feed and stay up for in quest of extra of your magnificent post.
    Additionally, I have shared your website in my social networks

  49. I do believe all of the concepts you have introduced for your
    post. They are very convincing and will definitely work.
    Still, the posts are too quick for newbies. May you please extend them a bit from subsequent time?

    Thank you for the post.

  50. After looking at a handful of the blog posts on your web site,
    I truly appreciate your technique of blogging.
    I book marked it to my bookmark website list and will be checking back soon.
    Take a look at my website as well and tell me your opinion.

  51. You actually make it seem so easy with your presentation but
    I find this matter to be actually something that I think I would never understand.

    It seems too complex and extremely broad for me. I am looking forward for your
    next post, I’ll try to get the hang of it!

  52. Hi there! This is my first visit to your blog!
    We are a team of volunteers and starting a new project in a community in the same
    niche. Your blog provided us beneficial information to work on. You have done a extraordinary job!

  53. Hi, I do believe this is a great blog. I stumbledupon it 😉 I am going to return once
    again since I book marked it. Money and freedom is the best way to change, may you be rich and continue to guide others.

  54. Thanks for your marvelous posting! I actually enjoyed reading it,
    you’re a great author. I will be sure to bookmark your blog and will come back down the road.

    I want to encourage continue your great posts, have a nice holiday weekend!

  55. Hi there, just became aware of your blog through Google, and found that it’s truly informative.
    I’m going to watch out for brussels. I will be grateful if
    you continue this in future. Numerous people will be benefited from your writing.

    Cheers!

  56. I am extremely inspired together with your writing talents
    as smartly as with the structure in your blog. Is this a paid theme or did you customize
    it your self? Either way keep up the nice quality writing, it’s rare to peer a
    great weblog like this one nowadays..

  57. I’m no longer positive where you are getting your info, however
    great topic. I needs to spend a while studying much more or working out more.
    Thanks for great information I was looking for this info for my mission.

  58. Can I just say what a relief to discover an individual who really knows what they’re talking about
    on the internet. You certainly know how to bring an issue to light and make it important.
    More people need to read this and understand this side of your story.

    I can’t believe you are not more popular because you definitely possess
    the gift.

  59. Excellent items from you, man. I have take into
    accout your stuff previous to and you’re just too great.
    I really like what you’ve acquired right here, certainly like what you are saying and the best way through which you assert it.
    You make it entertaining and you continue to care for to
    keep it sensible. I can not wait to read far more from you.
    That is really a great website.

  60. Today, I went to the beach front with my
    kids. I found a sea shell and gave it to my 4 year old
    daughter and said “You can hear the ocean if you put this to your ear.” She placed the shell to her ear and screamed.
    There was a hermit crab inside and it pinched her ear. She never wants to
    go back! LoL I know this is completely off topic but I had
    to tell someone!

  61. You actually make it appear really easy along with your
    presentation but I find this topic to be actually something that I feel
    I’d never understand. It seems too complex and extremely vast for me.

    I’m taking a look forward in your subsequent publish, I’ll attempt to get the cling of it!

  62. Its like you read my mind! You appear to know so much about this, like you
    wrote the book in it or something. I think that you can do with some
    pics to drive the message home a little bit, but other than that,
    this is great blog. A great read. I’ll definitely be back.

  63. Hey there! I just wanted to ask if you ever have any
    issues with hackers? My last blog (wordpress) was hacked and I ended up
    losing several weeks of hard work due to no backup. Do you
    have any methods to prevent hackers?

  64. hey there and thank you for your information – I’ve
    definitely picked up anything new from right here. I did however expertise some technical
    issues using this website, as I experienced to reload the website a lot of times previous to I could get it to
    load correctly. I had been wondering if your hosting is OK?
    Not that I am complaining, but slow loading instances times will very frequently affect your placement in google
    and can damage your quality score if advertising and marketing with Adwords.
    Anyway I am adding this RSS to my e-mail and can look out for much more of your respective
    interesting content. Ensure that you update this again very soon.

  65. My brother suggested I might like this web site. He was
    totally right. This post actually made my day. You cann’t imagine just how much time
    I had spent for this information! Thanks!

  66. I’ve been exploring for a little for any high quality articles or weblog posts in this kind of area .
    Exploring in Yahoo I at last stumbled upon this website. Studying this info So i’m satisfied to show that
    I’ve an incredibly good uncanny feeling I discovered
    just what I needed. I so much undoubtedly will make certain to do not fail
    to remember this site and give it a look regularly.

  67. I’m excited to discover this great site. I need to to
    thank you for your time for this particularly fantastic read!!
    I definitely appreciated every part of it and i also have you book-marked to
    look at new information in your blog.

  68. I am really impressed with your writing skills as well as with the layout on your weblog.
    Is this a paid theme or did you customize it yourself? Anyway keep up the nice quality writing, it’s rare to
    see a nice blog like this one today.

  69. I’m impressed, I must say. Rarely do I encounter a blog
    that’s both equally educative and entertaining, and without a
    doubt, you have hit the nail on the head. The problem is an issue
    that too few men and women are speaking intelligently about.
    I am very happy I came across this during my search for
    something concerning this.

  70. You really make it appear so easy with your presentation however I find this topic to be really something which I think I’d never understand.
    It kind of feels too complex and extremely extensive for me.
    I am having a look forward on your subsequent put up, I’ll
    try to get the grasp of it!

  71. I am really impressed with your writing skills as well
    as with the layout on your blog. Is this a paid theme or did you modify it
    yourself? Anyway keep up the excellent quality writing, it’s rare to see a great blog like this
    one today.

  72. Great weblog right here! Also your site a lot up fast! What host are you the usage of?
    Can I get your associate link for your host? I desire my web site loaded up as
    quickly as yours lol

  73. I’m truly enjoying the design and layout of your website.
    It’s a very easy on the eyes which makes it much more pleasant
    for me to come here and visit more often. Did you hire out a developer to
    create your theme? Great work!

  74. Hi! I could have sworn I’ve been to this website before but
    after checking through some of the post I realized it’s new to me.

    Anyways, I’m definitely happy I found it and I’ll be bookmarking and checking back frequently!

  75. Wonderful blog! Do you have any recommendations for aspiring writers?
    I’m planning to start my own site soon but I’m a little lost
    on everything. Would you suggest starting with a free platform like WordPress or go for
    a paid option? There are so many options out there that I’m completely overwhelmed ..
    Any ideas? Bless you!

  76. Hi there, i read your blog from time to time and i own a similar
    one and i was just curious if you get a lot of spam remarks?

    If so how do you protect against it, any plugin or anything
    you can suggest? I get so much lately it’s driving me mad so any support is
    very much appreciated.

  77. I loved as much as you’ll receive carried out right here.
    The sketch is tasteful, your authored material stylish.
    nonetheless, you command get got an shakiness over that you wish be delivering the following.
    unwell unquestionably come further formerly again since exactly the same
    nearly very often inside case you shield this increase.

  78. Do you mind if I quote a couple of your posts as long as I provide credit and sources back to your website? My blog is in the exact same area of interest as yours and my visitors would certainly benefit from a lot of the information you present here. Please let me know if this ok with you. Cheers!

  79. Hello i am kavin, its my first occasion to commenting anyplace, when i read this post i thought i could also create comment due to this good
    piece of writing.

  80. Hi! I know this is kinda off topic however , I’d figured I’d ask.
    Would you be interested in trading links or maybe guest authoring a blog
    post or vice-versa? My website addresses a lot of the same subjects as yours and I think we could greatly benefit from each other.

    If you’re interested feel free to shoot me an email.
    I look forward to hearing from you! Excellent blog by the way!

  81. Howdy! This post could not be written any better!
    Looking at this article reminds me of my previous roommate!
    He constantly kept talking about this. I most certainly will send
    this information to him. Pretty sure he’s going to have a great
    read. Thank you for sharing!

  82. Do you mind if I quote a couple of your articles as long as I
    provide credit and sources back to your webpage? My website is in the very same area of interest
    as yours and my visitors would certainly benefit from some of the information you present here.
    Please let me know if this ok with you. Thanks!

  83. Hello there, I found your web site via Google at the same time as searching for a comparable topic, your web site came up, it seems
    great. I’ve bookmarked it in my google bookmarks.
    Hi there, simply become aware of your weblog thru Google, and located that it’s really informative.
    I’m gonna be careful for brussels. I will appreciate if you continue this in future.
    Numerous people might be benefited out of your writing.
    Cheers!

  84. Howdy! I know this is sort of off-topic but I had to ask.
    Does operating a well-established blog such as yours require a large amount of work?
    I’m brand new to running a blog however I do write in my diary daily.
    I’d like to start a blog so I can easily share my own experience
    and views online. Please let me know if you have any kind of ideas or
    tips for new aspiring blog owners. Appreciate it!

  85. Very nice post. I simply stumbled upon your blog and wished to mention that I have truly loved surfing around your weblog posts.
    In any case I will be subscribing on your rss feed and I
    hope you write once more very soon!

  86. Good day very cool website!! Guy .. Excellent
    .. Wonderful .. I will bookmark your blog and take the feeds additionally?

    I am happy to seek out so many useful info right here
    within the post, we want develop more strategies in this
    regard, thanks for sharing. . . . . .

  87. Thank you for any other informative web site.
    The place else may I am getting that type of information written in such a perfect
    manner? I have a project that I’m just now running on, and I’ve been on the glance out for such information.

  88. Hmm is anyone else encountering problems with the pictures on this blog loading?
    I’m trying to determine if its a problem on my end or if it’s
    the blog. Any suggestions would be greatly
    appreciated.

  89. Hey there, I think your blog might be having browser compatibility issues.
    When I look at your website in Firefox, it looks fine but when opening in Internet Explorer,
    it has some overlapping. I just wanted to give you a quick
    heads up! Other then that, fantastic blog!

  90. Magnificent goods from you, man. I’ve understand your stuff previous to and you are just extremely fantastic.
    I actually like what you have acquired here, certainly like what you are saying and the way in which you say it.
    You make it entertaining and you still care for to
    keep it smart. I cant wait to read far more from you.
    This is actually a tremendous site.

  91. When I originally commented I clicked the “Notify me when new comments are added” checkbox and
    now each time a comment is added I get three e-mails with the same comment.
    Is there any way you can remove me from that service?
    Appreciate it!

  92. First of all I would like to say wonderful blog! I had a quick question that I’d
    like to ask if you don’t mind. I was interested to find out
    how you center yourself and clear your mind before writing.
    I have had a difficult time clearing my mind in getting my ideas out.
    I do take pleasure in writing but it just seems like the
    first 10 to 15 minutes are generally wasted just trying
    to figure out how to begin. Any ideas or hints? Thanks!

  93. My brother suggested I might like this web site. He was entirely right.
    This post truly made my day. You can not imagine simply how much time I had spent for
    this information! Thanks!

  94. What’s Happening i am new to this, I stumbled upon this I have found It
    positively useful and it has helped me out loads.

    I am hoping to give a contribution & aid different customers like its aided me.
    Great job.

  95. I seriously love your site.. Pleasant colors & theme. Did you develop this website yourself?
    Please reply back as I’m wanting to create my own website and would love to
    find out where you got this from or exactly what the theme
    is named. Thank you!

  96. Howdy I am so glad I found your website, I really found you by error, while I was looking on Aol
    for something else, Nonetheless I am here now and would just like to
    say kudos for a marvelous post and a all round enjoyable blog
    (I also love the theme/design), I don’t have
    time to look over it all at the minute but I have saved it
    and also included your RSS feeds, so when I have time I
    will be back to read a great deal more, Please do keep up the great jo.

  97. Attractive section of content. I just stumbled upon your website and in accession capital to assert that I acquire in fact enjoyed
    account your blog posts. Anyway I’ll be subscribing to your augment and even I achievement you access consistently fast.

  98. I have been exploring for a little bit for any high quality articles or weblog posts on this kind of house .
    Exploring in Yahoo I ultimately stumbled upon this web site.

    Reading this info So i’m glad to exhibit that I’ve a very
    good uncanny feeling I found out just what I needed. I so much
    certainly will make certain to don?t fail to remember
    this web site and provides it a look regularly.

  99. Having read this I thought it was really enlightening.
    I appreciate you spending some time and energy to put this informative article
    together. I once again find myself spending a
    lot of time both reading and commenting. But so what, it was still worthwhile!

  100. Greate article. Keep posting such kind of info on your site.
    Im really impressed by it.
    Hey there, You’ve done a fantastic job. I will certainly digg it and in my opinion recommend to
    my friends. I’m confident they will be benefited from this website.

  101. Hi! I just wanted to ask if you ever have any problems with
    hackers? My last blog (wordpress) was hacked and I
    ended up losing months of hard work due to no backup.

    Do you have any solutions to protect against hackers?

  102. I feel that is among the most significant info for me.
    And i’m satisfied reading your article. But want to remark
    on few normal issues, The web site taste is great, the articles is actually great :
    D. Just right job, cheers

  103. It’s really a great and helpful piece of information. I’m happy
    that you shared this helpful info with us. Please keep
    us up to date like this. Thank you for sharing.

  104. whoah this weblog is magnificent i really like reading
    your articles. Keep up the good work! You know, many
    persons are hunting around for this info, you can help them greatly.

  105. I’m amazed, I have to admit. Rarely do I encounter a blog that’s equally educative and entertaining, and without a doubt, you have hit the nail
    on the head. The issue is something which not enough men and women are speaking intelligently about.
    I’m very happy I found this in my hunt for something relating to
    this.

  106. This is really interesting, You’re an excessively professional blogger.
    I’ve joined your rss feed and stay up for seeking extra of your great
    post. Also, I’ve shared your website in my social networks

  107. Hmm it looks like your blog ate my first comment (it was super long) so I guess I’ll just sum it up what
    I had written and say, I’m thoroughly enjoying your blog.

    I as well am an aspiring blog blogger but I’m still new to the
    whole thing. Do you have any suggestions for first-time blog
    writers? I’d really appreciate it.

  108. Heya i’m for the first time here. I came across this board and I find It truly useful
    & it helped me out much. I hope to give something back
    and aid others like you aided me.

  109. Excellent items from you, man. I’ve take note your stuff previous to and you are simply extremely fantastic.
    I actually like what you have bought here, really like what you’re saying and the way in which
    through which you are saying it. You make it entertaining and you continue to take care
    of to stay it sensible. I can not wait to learn much more from you.
    This is actually a terrific web site.

  110. With havin so much content do you ever run into any problems of plagorism or copyright infringement?

    My site has a lot of exclusive content I’ve either authored myself or outsourced but it looks like a lot of it is popping it up all over the internet without my agreement.
    Do you know any methods to help stop content from being ripped off?

    I’d really appreciate it.

  111. Have you ever thought about writing an ebook or guest authoring on other blogs?

    I have a blog centered on the same topics you discuss and would really
    like to have you share some stories/information. I know my
    readers would value your work. If you are even remotely interested,
    feel free to shoot me an e mail.

  112. Hello there! I could have sworn I’ve visited this blog before but after browsing through some of
    the posts I realized it’s new to me. Anyhow, I’m
    definitely delighted I stumbled upon it and I’ll be bookmarking it and checking back regularly!

  113. Thank you for some other informative website. The place else
    could I get that kind of info written in such a perfect manner?

    I’ve a undertaking that I am simply now working on, and I’ve been on the glance out for such
    information.

  114. you’re in reality a good webmaster. The site loading speed is amazing.
    It kind of feels that you’re doing any distinctive trick.
    In addition, The contents are masterpiece.
    you have done a magnificent activity on this matter!

  115. Hmm it appears like your site ate my first comment (it was extremely long) so I
    guess I’ll just sum it up what I submitted and say, I’m thoroughly
    enjoying your blog. I too am an aspiring blog writer but I’m still new to
    everything. Do you have any tips for newbie blog writers? I’d
    genuinely appreciate it.

  116. My coder is trying to persuade me to move to .net from PHP.
    I have always disliked the idea because of the costs.
    But he’s tryiong none the less. I’ve been using WordPress on a variety
    of websites for about a year and am concerned about switching
    to another platform. I have heard great things about blogengine.net.
    Is there a way I can transfer all my wordpress content into it?

    Any kind of help would be greatly appreciated!

  117. I think this is one of the most significant info for me.

    And i am glad reading your article. But should remark on few general things, The website style is
    perfect, the articles is really excellent :
    D. Good job, cheers

  118. You have made some good points there. I checked on the internet for
    additional information about the issue and found most individuals will go
    along with your views on this site.

  119. That is very attention-grabbing, You are a
    very professional blogger. I have joined your rss feed and look ahead to searching
    for extra of your fantastic post. Also, I’ve
    shared your web site in my social networks

  120. We absolutely love your blog and find many of your post’s to be
    exactly what I’m looking for. can you offer guest writers to write content for yourself?
    I wouldn’t mind writing a post or elaborating on a lot of the
    subjects you write in relation to here. Again, awesome
    blog!

  121. Hello! I could have sworn I’ve been to this website before
    but after checking through some of the post I
    realized it’s new to me. Anyways, I’m definitely happy I found it and I’ll be book-marking and checking
    back frequently!

  122. Great weblog here! Also your site quite a bit up very fast!
    What web host are you the use of? Can I am getting
    your associate hyperlink to your host? I wish my website
    loaded up as fast as yours lol

  123. Do you have a spam issue on this site; I also am a blogger, and I was wanting
    to know your situation; many of us have created some nice methods and we are looking to swap strategies with others, please shoot me
    an email if interested.

  124. Superb website you have here but I was curious about if you
    knew of any user discussion forums that cover the same topics discussed in this article?
    I’d really like to be a part of group where I can get feed-back from other knowledgeable people
    that share the same interest. If you have any suggestions,
    please let me know. Thanks a lot!

  125. With havin so much written content do you ever run into any problems of plagorism
    or copyright violation? My site has a lot of exclusive content I’ve either authored myself or outsourced but it appears
    a lot of it is popping it up all over the web without my agreement.
    Do you know any methods to help reduce content from being ripped off?

    I’d really appreciate it.

  126. Hello, i think that i saw you visited my blog so i came to
    “return the favor”.I am attempting to find
    things to enhance my web site!I suppose its ok to use some of
    your ideas!!

  127. I’ve been surfing online more than 2 hours today, yet I never found any interesting
    article like yours. It is pretty worth enough for me. In my view, if all site owners and bloggers made good content as you
    did, the net will be a lot more useful than ever before.

  128. Thanks for ones marvelous posting! I certainly
    enjoyed reading it, you’re a great author.I will ensure that I bookmark your blog
    and will eventually come back sometime soon. I
    want to encourage that you continue your great writing, have a nice afternoon!

  129. You really make it seem really easy with your presentation but I to find this topic
    to be actually something which I feel I’d never understand.

    It kind of feels too complicated and extremely huge for me.
    I’m taking a look forward on your next put up, I’ll try to get the hold of it!

  130. Fantastic goods from you, man. I’ve understand your stuff previous to and you’re just too magnificent.
    I actually like what you have acquired here, really like what you’re saying and
    the way in which you say it. You make it entertaining and you still take
    care of to keep it smart. I cant wait to read much more from you.
    This is actually a tremendous site.

  131. My coder is trying to convince me to move to .net from PHP.
    I have always disliked the idea because of the
    expenses. But he’s tryiong none the less. I’ve been using Movable-type on a variety of websites for about a
    year and am concerned about switching to another platform.
    I have heard fantastic things about blogengine.net. Is there a way I can import all my wordpress posts into it?
    Any kind of help would be really appreciated!

  132. I think everything composed was very reasonable.
    However, think on this, suppose you were to write a
    killer title? I ain’t suggesting your information isn’t solid., but what if you added
    a headline to possibly grab people’s attention? I mean ozenero | Mobile & Web Programming Tutorials is
    kinda vanilla. You might glance at Yahoo’s front page and see how they
    write article titles to grab viewers interested. You
    might add a video or a picture or two to get readers excited about
    everything’ve written. In my opinion, it could bring your blog a little bit more interesting.

  133. I do believe all the ideas you’ve offered on your post.
    They’re very convincing and can certainly work. Still, the
    posts are too brief for newbies. Could you please extend them a bit from subsequent time?
    Thank you for the post.

  134. I think this is among the most vital info for me. And i am glad reading your
    article. But wanna remark on few general things, The site style is ideal,
    the articles is really nice : D. Good job, cheers

  135. Hello there! This post couldn’t be written any better! Looking at
    this article reminds me of my previous roommate! He
    continually kept talking about this. I am going to send this article
    to him. Pretty sure he will have a good read. Thank you for sharing!

  136. hello there and thank you for your info – I’ve definitely
    picked up something new from right here. I did however expertise a few technical issues using this web site, as I
    experienced to reload the site lots of times previous to I could get it to
    load correctly. I had been wondering if your web host is OK?
    Not that I am complaining, but slow loading instances times
    will often affect your placement in google and could damage your quality score if
    ads and marketing with Adwords. Well I am adding this
    RSS to my e-mail and can look out for much more of your respective exciting content.
    Ensure that you update this again soon.

  137. We are a gaggle of volunteers and opening a brand new scheme in our community.

    Your site provided us with valuable information to
    work on. You have done an impressive job and our whole community might be grateful
    to you.

  138. I was suggested this blog by way of my cousin. I am no
    longer sure whether this submit is written by him as nobody else recognise such exact approximately my difficulty.
    You’re incredible! Thank you!

  139. I do consider all of the ideas you’ve offered for your post.
    They are very convincing and will definitely work. Nonetheless, the posts are very short for beginners.
    May just you please prolong them a bit from next time? Thanks for the post.

  140. I will immediately seize your rss feed as I can’t
    in finding your e-mail subscription link or e-newsletter service.
    Do you have any? Kindly let me understand so that I may subscribe.
    Thanks.

  141. Wow! This blog looks just like my old one! It’s on a completely different subject but it has pretty much the same page layout and design. Great choice of colors!

  142. I loved as much as you will receive carried out right here.
    The sketch is tasteful, your authored material stylish.
    nonetheless, you command get bought an nervousness over that you wish be delivering
    the following. unwell unquestionably come further formerly again as exactly the same nearly a lot
    often inside case you shield this hike.

  143. Attractive component of content. I simply stumbled upon your blog and in accession capital to claim that I acquire actually enjoyed account your blog posts.
    Any way I’ll be subscribing in your augment and even I success you get entry to constantly fast.

  144. I think this is among the most vital information for me.
    And i am glad reading your article. But should remark on few general things, The website
    style is perfect, the articles is really excellent : D.
    Good job, cheers

  145. Awesome blog! Is your theme custom made or did you download
    it from somewhere? A design like yours with a few simple tweeks would really make my
    blog stand out. Please let me know where you got your theme.
    Bless you

  146. This is really fascinating, You are an excessively skilled blogger.
    I have joined your rss feed and look ahead to searching for more of your magnificent post.
    Also, I have shared your site in my social networks

  147. Please let me know if you’re looking for a article author for your blog.
    You have some really great articles and I believe I would be a good asset.
    If you ever want to take some of the load off, I’d absolutely love to write some content for your blog
    in exchange for a link back to mine. Please send me an email if interested.
    Thank you!

  148. I’ve been browsing online more than 3 hours today, yet I never found any interesting article like yours.

    It is pretty worth enough for me. In my opinion, if all website owners
    and bloggers made good content as you did, the internet will
    be a lot more useful than ever before.

  149. Write more, thats all I have to say. Literally, it seems as
    though you relied on the video to make your point.
    You obviously know what youre talking about, why waste your intelligence on just
    posting videos to your site when you could be giving us something informative to read?

  150. Write more, thats all I have to say. Literally, it seems as though you relied on the video to make
    your point. You definitely know what youre talking about, why waste your
    intelligence on just posting videos to your weblog when you could
    be giving us something enlightening to read?

  151. Hey would you mind sharing which blog platform you’re working with?
    I’m going to start my own blog soon but I’m having a hard
    time selecting between BlogEngine/Wordpress/B2evolution and Drupal.
    The reason I ask is because your design and style seems different then most blogs and I’m looking for something
    unique. P.S Apologies for getting off-topic but I had to ask!

  152. I was wondering if you ever thought of changing the page layout of your blog?
    Its very well written; I love what youve got to say.
    But maybe you could a little more in the way of content so people
    could connect with it better. Youve got an awful lot of text for only
    having 1 or two images. Maybe you could space it out better?

  153. Hey I know this is off topic but I was wondering if you knew of any
    widgets I could add to my blog that automatically tweet my newest twitter updates.
    I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this.
    Please let me know if you run into anything.
    I truly enjoy reading your blog and I look forward to
    your new updates.

  154. I was recommended this website by my cousin. I’m not sure whether this post is written by him as nobody
    else know such detailed about my difficulty. You’re wonderful!
    Thanks!

  155. Great blog right here! Additionally your site a lot up very fast!
    What host are you the usage of? Can I am getting your associate hyperlink on your host?
    I wish my web site loaded up as quickly as yours lol

  156. Good day! This is kind of off topic but I need some guidance from
    an established blog. Is it difficult to set up your
    own blog? I’m not very techincal but I can figure things
    out pretty fast. I’m thinking about creating my own but I’m not sure where to begin. Do you have
    any points or suggestions? Appreciate it

  157. hello there and thank you for your info – I have
    certainly picked up something new from right here.
    I did however expertise several technical issues using
    this site, since I experienced to reload the web site
    many times previous to I could get it to load correctly.
    I had been wondering if your hosting is OK? Not that I am complaining,
    but slow loading instances times will very frequently affect
    your placement in google and could damage your high quality score if ads and marketing with Adwords.
    Well I am adding this RSS to my e-mail and could look out for
    much more of your respective exciting content. Make sure you update this again soon.

  158. My relatives always say that I am killing my time here at net, but I know I am getting
    familiarity every day by reading thes fastidious articles or
    reviews.

  159. Do you mind if I quote a few of your posts as long as
    I provide credit and sources back to your webpage?
    My blog site is in the very same area of interest as yours
    and my users would truly benefit from a lot of the information you provide here.
    Please let me know if this okay with you. Appreciate it!

  160. Hi! I could have sworn I’ve been to this site before but after reading through some of the post I realized it’s new
    to me. Anyhow, I’m definitely delighted I found it
    and I’ll be bookmarking and checking back frequently!

  161. Hi there just wanted to give you a quick heads up.
    The text in your article seem to be running off the screen in Internet
    explorer. I’m not sure if this is a format issue or something to do with
    web browser compatibility but I figured I’d post to let you know.
    The layout look great though! Hope you get the issue resolved soon. Many thanks

  162. You actually make it appear really easy together with your
    presentation however I in finding this topic to be really something which
    I believe I’d by no means understand. It seems too complex
    and extremely vast for me. I’m looking forward in your next post,
    I’ll try to get the cling of it!

  163. An outstanding share! I’ve just forwarded this onto a co-worker who was conducting a little research on this.
    And he actually bought me breakfast simply because I found it for him…
    lol. So allow me to reword this…. Thanks for
    the meal!! But yeah, thanx for spending the time to discuss this subject here on your web site.

  164. Do you have a spam issue on this website; I also am a blogger, and I
    was curious about your situation; many of us have developed some nice practices and we are looking to trade methods with other folks, why not shoot me an e-mail if interested.

  165. Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet
    my newest twitter updates. I’ve been looking for a plug-in like
    this for quite some time and was hoping maybe you would have some experience with something like this.

    Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

  166. Hmm it appears like your blog ate my first comment (it was super
    long) so I guess I’ll just sum it up what I wrote and say, I’m thoroughly enjoying your blog.

    I too am an aspiring blog blogger but I’m still new to everything.
    Do you have any points for rookie blog writers? I’d genuinely appreciate it.